自从升级到XCode8 GM和iOS10以后,我通过Interface Builder创建的所有视图都不会在预期的时间内正确初始化。这意味着在viewDidLoad、cellForRowAtIndexPath、viewWillAppear等方法中,每个视图的frame大小都被设置为{1000,1000}。它们似乎在某个时候得到了纠正,但是太晚了。
首先遇到的问题是常见的圆角四边形效果在所有视图上都失败了:
view.layer.cornerRadius = view.frame.size.width/2
依赖帧大小来进行代码计算的任何内容,都会出现进一步的问题。
cellForRowAtIndexPath
在初始表格显示时,cellForRowAtIndexPath中的框架大小失败,但一旦滚动它就能正常工作。 willDisplayCell:forRowAtIndexPath也没有正确的框架大小。
我已经硬编码了一些值,但很明显这是非常糟糕的代码实践,而且在我的项目中数量相当多。
有没有办法或地方可以获取正确的框架大小?
编辑
我发现使用高度/宽度约束而不是框架宽度高度更可靠。虽然这可能增加需要链接项高度/宽度约束的许多新IBOutlets的开销。
现在,我创建了一个UIView类别,让我直接访问视图的高度/宽度约束,而无需IBOutlets。对于最小使用情况,小循环不会有太大问题。显然,对于尚未创建宽度/高度约束的IB项,结果不能保证为0,甚至更差。
-viewDidLoad似乎具有正确的框架大小,但是如果您在此处进行修改,通常会导致UI的视觉变化。
UIView+WidthHeightConstraints.h
@interface UIView (WidthHeightConstraints)
-(NSLayoutConstraint*)widthConstraint;
-(NSLayoutConstraint*)heightConstraint;
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute;
@end
UIView+WidthHeightConstraints.m
#import "UIView+WidthHeightConstraints.h"
@implementation UIView (WidthHeightConstraints)
-(NSLayoutConstraint*)widthConstraint{
return [self constraintForAttribute:NSLayoutAttributeWidth];
}
-(NSLayoutConstraint*)heightConstraint {
return [self constraintForAttribute:NSLayoutAttributeHeight];
}
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute {
NSLayoutConstraint *targetConstraint = nil;
for (NSLayoutConstraint *constraint in self.constraints) {
if (constraint.firstAttribute == attribute) {
targetConstraint = constraint;
break;
}
}
return targetConstraint;
}
@end
编辑2
上述分类已被证明只有部分有效。主要原因是iOS似乎会自动添加几个额外的高度/宽度约束副本,这些约束副本属于NSContentSizeLayoutConstraint类型,实际上与普通约束不同。NSContentSizeLayoutConstraint也是一个私有类,所以我无法使用isKindOfClass过滤它们。我还没有找到另一种有效测试它们的方法。这很烦人。