我正在开发一个应用程序,在其中我使用自动布局。我正在采取以下步骤:
viewDidLoad中创建一个按钮
超级self.view.translatesAutoresizingMaskIntoConstraints = NO;_button1 = UIButton UIButtonTypeRoundedRect;_button1.translatesAutoresizingMaskIntoConstraints = NO;_button1 setTitle:@"B“forState:UIControlStateNormal;self.view addSubview:_button1;updateViewConstraints方法中实现约束
(超级updateViewConstraints;self.view removeConstraints:self.view.constraints;if sharedApplication.statusBarOrientation){ NSLayoutConstraint *constraint = NSLayoutConstraint constraintWithItem:_button1属性:NSLayoutAttributeLeft relatedBy:NSLayoutRelationequaltoItem:self.view属性:NSLayoutAttributeLeft乘数:1.0F常数:100.0f;self.view addConstraint:constraint:constraint;NSLayoutConstraint *constraint 1= NSLayoutConstraint constraintWithItem:_button1属性:NSLayoutAttributeRight:NSLayoutRelationEqutoItem:self.view属性:NSLayoutAttributeRight:1.0F常量:-100.0f;self.view addConstraint:constraint:constraint 1;NSLayoutConstraint * NSLayoutConstraint 2= NSLayoutConstraint constraintWithItem:_button1属性:NSLayoutAttributeTop:NSLayoutAttributeBottom属性:NSLayoutAttributeBottom属性:1.0F常量:200.0f;self.view addConstraint:constraint3 2;NSLayoutConstraint *constraint3 3=NSLayoutConstraint constraintWithItem:_button1属性:NSLayoutAttributeBottom关联:NSLayoutAttributeBottom属性:NSLayoutAttributeBottom乘法器:1.0F常量:-100.0f;self.view附加条件:约束3;_button1.backgroundColor = UIColor redColor;}{ NSLayoutConstraint *constraint = NSLayoutConstraint constraintWithItem:_button1属性:NSLayoutAttributeLeft relatedBy:NSLayoutAttributeLeft属性:1.0F常量:200.0f;self.view加载项:约束;NSLayoutConstraint *约束1= NSLayoutConstraint constraintWithItem:_button1属性:NSLayoutAttributeRight:NSLayoutAttributeRight:NSLayoutAttributeRight属性:NSLayoutAttributeRight:1.0F常量:-200;self.view addConstraint:constraint 1;NSLayoutConstraint *constraint2 = NSLayoutConstraint constraintWithItem:_button1属性:NSLayoutAttributeTop:NayoutAttribuation等于constraint2:NSLayoutAttributeLeft常量:50.0f;self.view addConstraint:constraint2 2;NSLayoutConstraint *constraint2 3= NSLayoutConstraint constraintWithItem:_button1属性:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqutoItem:self.view属性:NSLayoutAttributeBottom乘数:1.0F常量:-50.0f;self.view addConstraint:constraint2 3;_button1.backgroundColor = UIColor blueColor;}但是,当我切换设备方向时,控制台会打印以下内容:
不能同时满足约束。可能下面列表中至少有一个约束是您不想要的。尝试如下:(1)查看每个约束,并尝试找出您不期望的;(2)找到添加了不需要的约束的代码并修复它。(注意:如果您看到的是您不理解的NSAutoresizingMaskLayoutConstraints,请参阅UIView属性translatesAutoresizingMaskIntoConstraints的文档)( "UIView:0x8a461c0 (名称:‘AC.26’:UIWindow:0x8a42970 )>“、"”、“UIButton:0x8a45e0(名称:‘’\‘:UIView:0x8a461c0 )>”、“ 将尝试通过打破objc_exception_throw上的约束中断来恢复,以便在调试器中捕捉到这一点。中列出的UIConstraintBasedLayoutDebugging类别中的UIView方法也可能有所帮助。
有人能告诉我这个布局有什么问题吗?
发布于 2013-12-02 16:19:46
问题是,在为按钮设置约束的同时,您正在updateViewConstraints中调用updateViewConstraints。因此,当您从景观过渡到纵向时,仍然有景观按钮约束(在纵向中是无法满足的),但是要求主视图更新其(纵向)约束。如果在删除所有现有按钮约束后将调用移动到[super updateViewConstraints]的任何地方,那么您应该处于良好的状态。
几个旁人:
发布于 2013-12-02 17:46:45
这也可以在不检查方向的情况下完成,方法是使用约束的乘数和常量值来创建一个单独的约束(对于每个方向),该约束对纵向和横向都有效(如果您在情节提要中创建视图,则需要在添加这些约束之前删除其中的任何约束-您可以通过在属性检查器中检查每个要删除的约束的“占位符-在构建时删除”框中的“占位符-删除”框)来自动完成这些操作。在你的特殊情况下,我认为这些价值观是有效的:
- (void)viewDidLoad {
[super viewDidLoad];
_button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
_button1.translatesAutoresizingMaskIntoConstraints = NO;
[_button1 setTitle:@"B" forState:UIControlStateNormal];
[self.view addSubview:_button1];
NSLayoutConstraint *topCon = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeTop relatedBy:0 toItem:self.view attribute:NSLayoutAttributeBottom multiplier:.9375 constant:-250];
NSLayoutConstraint *bottomCon = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeBottom relatedBy:0 toItem:self.view attribute:NSLayoutAttributeBottom multiplier:.6875 constant:50];
NSLayoutConstraint *leftCon = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeLeft relatedBy:0 toItem:self.view attribute:NSLayoutAttributeRight multiplier:.625 constant:-100];
NSLayoutConstraint *rightCon = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeRight relatedBy:0 toItem:self.view attribute:NSLayoutAttributeRight multiplier:.375 constant:100];
[self.view addConstraints:@[topCon,bottomCon,rightCon,leftCon]];
}注意,self.view的属性是顶部约束的底部,左边约束的右边。在使用乘法器时,您必须这样做,因为左边和顶部属性值为零,所以乘任何东西都是无用的。
用手计算这些值是件很痛苦的事,所以我并不是这样设置的。相反,我已经在NSLayoutConstraint上编写了一个类别,它允许我设置这样的约束(在http://jmp.sh/v/fgHhRNX2twlrgG338CDz中可以找到带有这个类别的exampleProject ):
[self.view addConstraint:[NSLayoutConstraint rightConstraintForView:_button1 viewAttribute:NSLayoutAttributeRight superview:self.view portraitValue:100 landscapeValue:200]];
[self.view addConstraint:[NSLayoutConstraint topConstraintForView:_button1 viewAttribute:NSLayoutAttributeTop superview:self.view portraitValue:200 landscapeValue:50]];
[self.view addConstraint:[NSLayoutConstraint bottomConstraintForView:_button1 viewAttribute:NSLayoutAttributeBottom superview:self.view portraitValue:100 landscapeValue:50]];
[self.view addConstraint:[NSLayoutConstraint leftConstraintForView:_button1 viewAttribute:NSLayoutAttributeLeft superview:self.view portraitValue:100 landscapeValue:200]];发布于 2013-12-02 15:49:02
通常,布局约束是在IB中构建的,然后根据方向更改进行调整,而不是像您想要的那样放弃和重新创建方向更改的约束。
无论如何,问题似乎是您没有删除所有所需的约束。行[self.view removeConstraints:self.view.constraints];只删除视图本身的约束,并忽略了可能存在与view相关的其他视图(即超级视图)的约束这一事实。
我不确定这是否是您的问题,但我会尝试调整现有的约束,看看这是否解决了问题。如果对您有帮助的话,您可以为布局约束制作IBOutlet。
https://stackoverflow.com/questions/20331148
复制相似问题