自动布局后使视图变成圆形

9

我有一个包含自定义单元格的tableview,这些单元格是使用带有标识符的AutoLayout构建的storyboard

其中一个子视图需要变成圆形(layer.cornerRadius = width/2),它一开始是正方形。

我尝试在layoutSubviews()中实现,但似乎在AutoLayout改变大小之前就已被调用了...didMoveToSuperview()也一样。

AutoLayout更改其大小后,更新我的子视图类似于这样的东西的正确函数在哪里?

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell_small") as! Cell
    ...
    return cell
}

// In Cell

override func layoutSubviews() {
    rankLabel.layer.cornerRadius = rankLabel.bounds.width/2
    rankLabel.layer.masksToBounds = true
}

override func didMoveToSuperview() {
    rankLabel.layer.cornerRadius = rankLabel.bounds.width/2
    rankLabel.layer.masksToBounds = true
}

结果:

解释: 无需翻译。

cellForRowAtIndexPath在布局之前被调用,可以参考下面的答案,你可以使用willDisplayCell。 - Christian
这个问题我也遇到了,有什么新的消息吗?我在 - (void) layoutSubviews 方法中添加了两行代码。确实解决了问题,但是在单元格显示一段时间后会出现明显的形状改变。 - JonSlowCN
你必须对每个你想改变形状的视图进行子类化,然后在它的layoutSubviews内部进行形状调整。 - Arbitur
@LordSpark,请检查我刚才做出的答案。 - Arbitur
@Arbitur 非常感谢! - JonSlowCN
显示剩余9条评论
6个回答

15

我最终做的是创建了一个名为RoundView的类。

class RoundView:UIView {
    override func layoutSubviews() {
        super.layoutSubviews()

        self.layer.cornerRadius = self.bounds.width/2
        self.layer.masksToBounds = true
    }
}

然后我将其应用于我需要变圆的每个视图。因此,在Storyboard中,我将RoundView添加到Custom Class中。

发生的情况是,如果您查看Storyboard的源代码(XML),则每个视图的大小都是整个屏幕的大小,您可以在自己的SB代码中查看。因此,尝试在父视图的layoutSubviews()中添加等于width/2的圆角半径时,子视图的框架还没有正确设置。因此,圆角半径的值为320/2而不是50/2,这就是为什么它变形了的原因。


3

1. 创建一个自定义的UIView类别

#import <UIKit/UIKit.h>
@interface RoundView : UIView

@end
#import "RoundView.h"

2.添加layoutSubviews方法并设置圆角。

@implementation RoundView

-(void)layoutSubviews{

[super layoutSubviews];

self.layer.cornerRadius = self.bounds.size.width/2;

self.layer.masksToBounds = true;

}

3.将您的UIView作为RoundView的子类,并运行应用程序,您将看到圆形视图。


1
尝试像这样对UITableViewCell进行子类化:

@interface RoundingCell : UITableViewCell

@property (nonatomic,weak) IBOutlet UILabel * someLabel;

@end

@implementation RoundingCell

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.someLabel.layer.cornerRadius = CGRectGetHeight(self.someLabel.bounds)/2;
    self.someLabel.layer.masksToBounds = YES;
}

@end

使用此类作为所需单元格的类,以及IBOutlet连接。

1

我也曾遇到过ImageView的问题,最后通过继承UIImageView解决了问题。

@interface MyImageView : UIImageView

@end

@implementation MyImageView

-(void)layoutSubviews
{
    [super layoutSubviews];    
    self.layer.cornerRadius = self.bounds.size.width / 2.0;
}
@end

0

很奇怪,我只是使用你的代码(同时也使用自动布局)就可以制作出我的圆形单元格。

唯一的区别是,我使用的是frame而不是bounds(除以2)。你试过这样做吗?

否则,你可以使用自定义单元格,在-awakeFromNib中设置相同的圆角方式,这样你就不必在每个单元格中都进行设置了。


我已经按照这种方式进行了结构化:contentView->UIView->UILabel。也许我需要对该UIView进行子类化,并在awakeFromNib或layoutSubViews中使UILabel变圆? - Arbitur
еҰӮжһңжӮЁеңЁи§Ҷеӣҫдёӯжңүж ҮзӯҫпјҢеҲҷеҝ…йЎ»жӢҘжңүеҸҜд»ҘдҪҝз”Ёзҡ„IBOutletsгҖӮзұ»дјјcell.myView.layer.frame.width/2иҝҷж ·зҡ„д»Јз Ғеә”иҜҘеҸҜд»Ҙиғңд»»жӯӨе·ҘдҪңгҖӮеҪ“然пјҢдёҚиҰҒеҝҳи®°жҺ©з ҒгҖӮ - Gil Sand

-1

您有两个选项:

  1. 创建一个自定义类YourCell,并将代码添加到initWithCoder方法中
  2. 向您的ViewController添加一个方法

如下所示

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

并在其中进行更改。要访问单元格,您需要调用

[(YourCell *)cell view]....

都没起作用 :( 而且我认为 iniWithCoder 永远不会起作用,因为它是在任何其他东西之前调用的 :P - Arbitur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接