Gau*_*ani 6 cocoa-touch objective-c ios autolayout
我正在使用添加视图作为子视图[self.view addSubview:myView].这在纵向模式下工作正常.但是,它在景观中根本不起作用.如何以编程方式添加布局约束?
我的视图目前看起来像是纵向矩形,我需要它在横向模式下看起来像横向矩形.
我尝试使用此代码来查看代码中的约束如何工作,但它总是导致异常.代码是:
[self.view addSubview:_preView];
NSLayoutConstraint *myConstraint = [NSLayoutConstraint
constraintWithItem:_preView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view.superview
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-239];
[_preView addConstraint:myConstraint];
Run Code Online (Sandbox Code Playgroud)
这总是会导致异常.我知道上面的代码只是试图确保预览的底部高于主视图底部239px.但这也不起作用.
你可以帮我解决这个问题,以便我能解决景观问题吗?
UPDATE
生成的异常是:
2013-08-05 16:13:28.889 Sample Code[33553:c07] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint:<NSLayoutConstraint:0x912c430 UIView:0x8561340.bottom == UILayoutContainerView:0x8257340.bottom - 20> view:<UIView: 0x85774e0; frame = (0 0; 320 568); opaque = NO; autoresize = W+H; autoresizesSubviews = NO; layer = <CALayer: 0x8577490>>'
*** First throw call stack:
(0x1a04012 0x173be7e 0x1a03deb 0x12ee4a0 0xbb983e 0xbb9a27 0xbb9b76 0xbb9d3b 0xbb9c4d 0x1c0d9 0x11395b3 0x19c3376 0x19c2e06 0x19aaa82 0x19a9f44 0x19a9e1b 0x24027e3 0x2402668 0x67fffc 0x2d3d 0x2c65)
libc++abi.dylib: terminate called throwing an exception
(lldb)
我在添加约束之前添加了子视图,所以我很确定视图是在层次结构中.
更新2
我在IB中将父视图的属性设置为"Autoresize Subviews".现在,当设备转动时,子视图会转换为横向矩形,但它太窄.我现在需要代码来确保它的宽度正确吗?
Rob*_*Rob 37
几点意见:
您的约束引用toItem的self.view.superview.我猜你的意思self.view.
您正在添加约束_preView,但您应该将其添加到self.view(如果您进行上述更改;如果不是,则使用self.view.superview).您始终将约束添加到最近的共享父级.
对于您以编程方式创建的视图,请确保设置translatesAutoresizingMaskIntoConstraints为NO.
从而:
_preView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_preView];
NSLayoutConstraint *myConstraint = [NSLayoutConstraint constraintWithItem:_preView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-239];
[self.view addConstraint:myConstraint];
Run Code Online (Sandbox Code Playgroud)离线聊天,最后两个观察结果:
你的约束是模棱两可的.将来,您可以通过在调试器中运行应用程序来识别,在应用程序运行时点击暂停按钮(
)然后在(lldb)提示符下,您可以输入
po [[UIWindow keyWindow] _autolayoutTrace]

如果你看到AMBIGUOUS LAYOUT,那么你的约束不是完全限定的(因此你会得到不可预测的行为).如果添加缺少的约束,则应该能够消除此警告.
如果要为基于约束的视图设置动画,则可以设置更改constant属性的动画constraints,而不是通过frame自己更改属性.例如:
// create subview
UIView *subview = [[UIView alloc] init];
subview.backgroundColor = [UIColor lightGrayColor];
subview.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:subview];
// create dictionary for VFL commands
NSDictionary *views = @{@"subview" : subview, @"superview" : self.view};
// add horizontal constraints
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview]|" options:0 metrics:nil views:views]];
// set the height of the offscreen subview to be the same as its superview
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[subview(==superview)]" options:0 metrics:nil views:views]];
// set the location of the subview to be just off screen below the current view
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:self.view.bounds.size.height];
[self.view addConstraint:constraint];
// then in two seconds, animate this subview back on-screen (i.e. change the top constraint `constant` to zero)
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
constraint.constant = 0.0;
[UIView animateWithDuration:1.0
animations:^{
[self.view layoutIfNeeded];
}];
});
Run Code Online (Sandbox Code Playgroud)