iOS 10 GM 和 xcode 8 GM 导致视图因 roundedCorners 和 clipsToBounds 而消失

iOS 10 GM with xcode 8 GM causes views to disappear due to roundedCorners & clipsToBounds

我使用 iOS 10 Beta 7 和 Xcode 8 beta 测试了我的应用程序,一切正常。然而,就在几分钟前,我安装了现在可用的 GM 版本,并遇到了一个奇怪的问题。

我在我的应用程序中使用自定义 table 视图单元格,在我的自定义单元格中我使用 cornerRadiusclipsToBounds 来创建圆形视图。

- (void)awakeFromNib {
    [super awakeFromNib];
    self.tag2label.layer.cornerRadius=self.tag2label.frame.size.height/2;
    self.tag2label.clipsToBounds=YES;
}

这在以前看起来还不错,但是在新的 GM 发布中,所有圆角的视图都消失了。这发生在 UIViewUILabelsUIButtons 上。

我在下面解决了这个问题。

我不确定这是否是新要求,但我通过在执行任何 cornerRadius 之前添加 [self layoutIfNeeded]; 解决了这个问题。所以我的新习惯 awakeFromNib 看起来像这样:

- (void)awakeFromNib {
    [super awakeFromNib];
    [self layoutIfNeeded];
    self.tag2label.layer.cornerRadius=self.tag2label.frame.size.height/2;
    self.tag2label.clipsToBounds=YES;
}

现在他们看起来都很好。

cornerRadius 本身工作正常,但框架上的大小报告不正确。这就是为什么 layoutIfNeeded 解决了这个问题。

您可以像这样创建视图的子类:

@implementation RoundImageView

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        self.layer.masksToBounds = YES;
        self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width)/2;
        [self addObserver:self
               forKeyPath:@"bounds"
                  options:NSKeyValueObservingOptionNew
                  context:(__bridge void * _Nullable)(self)];
    }
    return self;
}

-(void)dealloc
{
    [self removeObserver:self
              forKeyPath:@"bounds"
                 context:(__bridge void * _Nullable)(self)];
}

-(void)observeValueForKeyPath:(NSString *)keyPath
                     ofObject:(id)object
                       change:(NSDictionary<NSString *,id> *)change
                      context:(void *)context
{
    if(context == (__bridge void * _Nullable)(self) && object == self && [keyPath isEqualToString:@"bounds"])
    {
        self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width)/2;
    }
}

@end

所以您总是有适当的圆角。

我使用这种方法,升级到 Xcode8 和 iOS10 没有问题。

我在迁移到 TVOS 10 时遇到了同样的问题。删除自动布局约束并在情节提要中使用新的 Autoresizing 设置为我解决了这个问题。

我的观察是 iOS10 / TVOS 10 在调用 awakeFromNib 之前没有布局基于自动布局的视图,而是在调用相同方法之前使用自动调整大小掩码布局视图。

使用 cornerRadius=height/2 修复不可见视图创建类别 UIView+LayoutFix

在文件 UIView+LayoutFix.m 添加代码:

- (void)awakeFromNib {
    [super awakeFromNib];
    [self layoutIfNeeded];
}

将类别添加到 YourProject.PCH 文件。

只有在您的视图中使用 [super awakeFromNib] 才会起作用:

MyView.m

- (void)awakeFromNib {
    [super awakeFromNib];
    ...
}

您还可以在调试视图层次结构中看到该视图,但在应用程序中看不到它。

您必须在受影响的 masked/clipped 视图上调用 layoutIfNeeded

(例如,如果您有一个 UIImageView 并在其层上执行 masksToBounds,并且您无法在应用程序中看到视图等)