首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Autolayout问题

Autolayout问题
EN

Stack Overflow用户
提问于 2013-12-02 14:52:07
回答 5查看 1.1K关注 0票数 2

我正在开发一个应用程序,在其中我使用自动布局。我正在采取以下步骤:

  1. 步骤1:在viewDidLoad中创建一个按钮 超级self.view.translatesAutoresizingMaskIntoConstraints = NO;_button1 = UIButton UIButtonTypeRoundedRect;_button1.translatesAutoresizingMaskIntoConstraints = NO;_button1 setTitle:@"B“forState:UIControlStateNormal;self.view addSubview:_button1;
  2. 步骤2:在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方法也可能有所帮助。

有人能告诉我这个布局有什么问题吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2013-12-02 16:19:46

问题是,在为按钮设置约束的同时,您正在updateViewConstraints中调用updateViewConstraints。因此,当您从景观过渡到纵向时,仍然有景观按钮约束(在纵向中是无法满足的),但是要求主视图更新其(纵向)约束。如果在删除所有现有按钮约束后将调用移动到[super updateViewConstraints]的任何地方,那么您应该处于良好的状态。

几个旁人:

  1. 如果使用情节提要/NIBS,则应删除以下一行: self.view.translatesAutoresizingMaskIntoConstraints = NO; 但请保持这句话: _button1.translatesAutoresizingMaskIntoConstraints = NO;
  2. 我会提防大规模取消所有的限制。我通常保留想要删除的约束的数组,这样我就可以轻松地删除需要删除的约束并进行重构。在您的示例中,删除所有内容可能很好,但是随着您向视图添加越来越多的约束,跟踪要删除和重构的内容可能会更容易: @property (非原子,强) NSArray *verticalConstraint;@property (非原子,强) NSArray *水平约束;
  3. 我可能建议使用VFL,它更简洁一些:

  • (void)updateViewConstraints { if (self.horizontalConstraints) self.view removeConstraints:self.horizontalConstraints;if (self.verticalConstraints) self.view removeConstraints:self.verticalConstraints;self.verticalConstraints;NSDictionary *views = NSDictionaryOfVariableBindings(_button1);NSDictionary *度量=0;(如果(UIInterfaceOrientationIsPortrait(UIApplication sharedApplication.statusBarOrientation){指标=@{@“左”:@100,@“右”:@100,@“顶”:@200,@“底部”:@100};_button1.backgroundColor = UIColor redColor;}{指标=@{@“左”:@200,@“右”:@200,@“顶”:@50,@“底部”:@50};_button1.backgroundColor = UIColor blueColor;} constraintsWithVisualFormat:@"H:|-(left)-_button1-(right)-|“= [NSLayoutConstraint self.horizontalConstraints选项:0度量:度量视图:视图];self.verticalConstraints = [NSLayoutConstraint self.horizontalConstraints选项:0度量:度量视图:视图];self.view addConstraints:self.horizontalConstraints;self.view addConstraints:self.verticalConstraints;}
票数 2
EN

Stack Overflow用户

发布于 2013-12-02 17:46:45

这也可以在不检查方向的情况下完成,方法是使用约束的乘数和常量值来创建一个单独的约束(对于每个方向),该约束对纵向和横向都有效(如果您在情节提要中创建视图,则需要在添加这些约束之前删除其中的任何约束-您可以通过在属性检查器中检查每个要删除的约束的“占位符-在构建时删除”框中的“占位符-删除”框)来自动完成这些操作。在你的特殊情况下,我认为这些价值观是有效的:

代码语言:javascript
复制
- (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 ):

代码语言:javascript
复制
[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]];
票数 1
EN

Stack Overflow用户

发布于 2013-12-02 15:49:02

通常,布局约束是在IB中构建的,然后根据方向更改进行调整,而不是像您想要的那样放弃和重新创建方向更改的约束。

无论如何,问题似乎是您没有删除所有所需的约束。行[self.view removeConstraints:self.view.constraints];只删除视图本身的约束,并忽略了可能存在与view相关的其他视图(即超级视图)的约束这一事实。

我不确定这是否是您的问题,但我会尝试调整现有的约束,看看这是否解决了问题。如果对您有帮助的话,您可以为布局约束制作IBOutlet

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20331148

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档