自升级到XCode8 GM和ios10以来,通过Interface Builder创建的所有视图都没有正确初始化,直到比预期要晚得多.这意味着在viewDidLoad,cellForRowAtIndexPath,viewWillAppear等中,每个视图的帧大小都设置为{1000,1000}.在某些时候他们似乎是正确的,但它为时已晚.
遇到的第一个问题是全面的角落圆角失败:
view.layer.cornerRadius = view.frame.size.width/2
Run Code Online (Sandbox Code Playgroud)
对于依赖于帧大小在代码中进行计算的任何事情,都会出现进一步的问题.
cellForRowAtIndexPath
Run Code Online (Sandbox Code Playgroud)
对于cellForRowAtIndexPath,帧大小在初始表显示时失败,但滚动后它可以正常工作.willDisplayCell:forRowAtIndexPath也没有正确的帧大小.
我已经对一些值进行了硬编码,但显然这是非常糟糕的代码实践,在我的项目中也是如此.
有没有办法或地方获得正确的框架尺寸?
编辑
我发现使用高度/宽度约束而不是帧宽高度更可靠.这可能会增加需要大量新IBOutlet的开销,以链接项目的高度/宽度约束.
现在我已经创建了一个UIView类,它允许我在没有IBOutlets的情况下直接访问View的高度/宽度约束.对于最小的使用,小循环不应该是一个大问题.对于没有明显创建宽度/高度约束的IB项目,不能保证结果.可能最好为常数返回0,或者更糟.此外,如果您没有高度/宽度约束,并且您的视图基于前导/尾随约束动态调整大小,则这将不起作用.
-viewDidLoad似乎具有正确的帧大小,但如果您在此处进行修改,通常会导致UI的可视更改.
UIView的+ WidthHeightConstraints.h
@interface UIView (WidthHeightConstraints)
-(NSLayoutConstraint*)widthConstraint;
-(NSLayoutConstraint*)heightConstraint;
-(NSLayoutConstraint*)constraintForAttribute:(NSLayoutAttribute)attribute;
@end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
编辑2
事实证明,上述类别只是部分有效.主要是因为ios似乎自动添加一些额外的高度/宽度约束重复项,类型为NSContentSizeLayoutConstraint,实际上与普通约束的大小不同.NSContentSizeLayoutConstraint也是一个私有类,所以我不能做isKindOfClass来过滤掉那些.我还没有找到另一种有效测试的方法.这很烦人.