在使用 UIScrollView 时,我注意到一些关于自动布局和内容插入的奇怪行为;以下面的代码为例:
- (void) loadView
{
UIScrollView * scroller = [[UIScrollView alloc] init];
scroller.backgroundColor = [UIColor orangeColor];
UILabel * label = [[UILabel alloc] init];
label.backgroundColor = [UIColor blueColor];
label.translatesAutoresizingMaskIntoConstraints = NO;
[scroller addSubview:label];
[scroller addConstraint: [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:scroller attribute:NSLayoutAttributeLeft multiplier:1.0 constant:40]];
[scroller addConstraint: [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:scroller attribute:NSLayoutAttributeTop multiplier:1.0 constant:20]];
[scroller addConstraint: [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:240]];
[scroller addConstraint: [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:44]];
self.view = scroller;
scroller.contentInset = UIEdgeInsetsMake(44, 0, 0, 0); //this is the game changer
}
如果没有更改内容插图的最后一行,UILabel 就如预期的那样位于 (40, 20) 处。更改内容插图时,标签移动到 (40, 108),而不是 (40, 64);顶部内容插图以某种方式翻了一番。如果 UILabel 是使用设置框架创建的并且没有这些约束:
- (void) loadView
{
UIScrollView * scroller = [[UIScrollView alloc] init];
scroller.backgroundColor = [UIColor orangeColor];
CGRect frame = CGRectMake(40, 20, 240, 44);
UILabel * label = [[UILabel alloc] initWithFrame:frame];
label.backgroundColor = [UIColor blueColor];
[scroller addSubview:label];
self.view = scroller;
scroller.contentInset = UIEdgeInsetsMake(44, 0, 0, 0);
}
然后它的行为符合预期的 (40, 20) 和 (40, 64),具体取决于内容插图。
我检查了文件并尝试翻转一些开关,但仍然无法弄清楚原因。
顺便说一句,这是 IOS(6) 模拟器的结果,我还没有在设备上尝试过。
PS 事情在 IOS7 模拟器上按预期出现,除了新状态栏行为的不同。