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 视图单元格,在我的自定义单元格中我使用 cornerRadius
和 clipsToBounds
来创建圆形视图。
- (void)awakeFromNib {
[super awakeFromNib];
self.tag2label.layer.cornerRadius=self.tag2label.frame.size.height/2;
self.tag2label.clipsToBounds=YES;
}
这在以前看起来还不错,但是在新的 GM 发布中,所有圆角的视图都消失了。这发生在 UIView
、UILabels
和 UIButtons
上。
我在下面解决了这个问题。
我不确定这是否是新要求,但我通过在执行任何 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
,并且您无法在应用程序中看到视图等)
我使用 iOS 10 Beta 7 和 Xcode 8 beta 测试了我的应用程序,一切正常。然而,就在几分钟前,我安装了现在可用的 GM 版本,并遇到了一个奇怪的问题。
我在我的应用程序中使用自定义 table 视图单元格,在我的自定义单元格中我使用 cornerRadius
和 clipsToBounds
来创建圆形视图。
- (void)awakeFromNib {
[super awakeFromNib];
self.tag2label.layer.cornerRadius=self.tag2label.frame.size.height/2;
self.tag2label.clipsToBounds=YES;
}
这在以前看起来还不错,但是在新的 GM 发布中,所有圆角的视图都消失了。这发生在 UIView
、UILabels
和 UIButtons
上。
我在下面解决了这个问题。
我不确定这是否是新要求,但我通过在执行任何 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
,并且您无法在应用程序中看到视图等)