自从升级到XCode8 GM和ios10之后,我通过Interface Builder创建的所有视图都无法正确初始化,直到比预期晚了很多.这意味着在viewDidLoad、cellForRowAtIndexPath、ViewWillDisplay等中,每个视图的帧大小都设置为{10001000}.在某些时候,他们似乎是正确的,但为时已晚.
遇到的第一个问题是,常见的拐角圆角未能全面解决:
view.layer.cornerRadius = view.frame.size.width/2
在代码中,任何依赖帧大小进行计算的东西都会出现进一步的问题.
cellForRowAtIndexPath
对于cellForRowAtIndexPath,帧大小在初始表格显示时失败,但在滚动它之后就可以正常工作.willDisplayCell:forRowAtIndexPath也没有正确的帧大小.
我已经硬编码了一些值,但显然这是非常糟糕的代码实践,在我的项目中也是如此.
有没有一种方法或地方可以获得正确的框架尺寸?
EDIT
我发现使用"高度/宽度"约束而不是"帧宽度-高度"更可靠.不过,这可能会增加需要大量新的IBOutlet来链接项目的高度/宽度限制的开销.
目前,我已经创建了一个UIView类别,它允许我直接访问视图的高度/宽度约束,而无需使用IBOutlet.对于最小的使用,小循环应该不是什么大问题.对于没有明显创建的宽度/高度限制的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
EDIT 2
事实证明,上述类别仅部分有效.主要是因为ios似乎会自动添加两个额外的高度/宽度约束副本,它们属于NSContentSizeLayoutConstraint类型,实际上与普通约束的大小不同.NSContentSizeLayoutConstraint也是一个私有类,所以我不能用类来过滤掉它们.我还没有找到另一种有效的测试方法.这很烦人.