我正在开发一个使用自动布局的应用程序。我正在执行以下步骤:
第 1 步:在
viewDidLoad
中创建一个按钮[super viewDidLoad]; self.view.translatesAutoresizingMaskIntoConstraints = NO; _button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; _button1.translatesAutoresizingMaskIntoConstraints = NO; [_button1 setTitle:@"B" forState:UIControlStateNormal]; [self.view addSubview:_button1];
第 2 步:在
updateViewConstraints
方法中实现约束[super updateViewConstraints]; [self.view removeConstraints:self.view.constraints]; if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) { NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0f constant:100.0f]; [self.view addConstraint:constraint]; NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0f constant:-100.0f]; [self.view addConstraint:constraint1]; NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0f constant:200.0f]; [self.view addConstraint:constraint2]; NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-100.0f]; [self.view addConstraint:constraint3]; _button1.backgroundColor = [UIColor redColor]; } else{ NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0f constant:200.0f]; [self.view addConstraint:constraint]; NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0f constant:-200]; [self.view addConstraint:constraint1]; NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0f constant:50.0f]; [self.view addConstraint:constraint2]; NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:_button1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0f constant:-50.0f]; [self.view addConstraint:constraint3]; _button1.backgroundColor = [UIColor blueColor]; }
但是当我切换设备方向时,控制台会打印以下内容:
Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "UIView:0x8a461c0 (Names: '|':UIWindow:0x8a42970 )>", "", "", "UIButton:0x8a45ea0 (Names: '|':UIView:0x8a461c0 )>", "" )
Will attempt to recover by breaking constraint
Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in may also be helpful.
谁能告诉我这个布局有什么问题吗?
最佳答案
问题在于,您在 updateViewConstraints
中调用 [super updateViewConstraints]
,而按钮仍有约束。因此,当您从横向过渡到纵向时,您仍然具有横向按钮约束(在纵向中无法满足),但要求主视图更新其(纵向)约束。如果在删除所有现有按钮约束后将调用移至 [super updateViewConstraints]
任何位置,那么您应该处于良好状态。
一些旁白:
如果使用 Storyboard/NIBS,您应该删除以下行:
self.view.translatesAutoresizingMaskIntoConstraints = NO;
但请保留以下内容:
_button1.translatesAutoresizingMaskIntoConstraints = NO;
我对全面取消所有限制持谨慎态度。我通常保留要删除的约束的数组,这样我就可以轻松删除那些我需要删除并将要重建的约束。在您的情况下,删除所有内容可能没问题,但是当您向 View 添加越来越多的约束时,跟踪您想要删除和重建的内容可能会更容易:
@property (nonatomic, strong) NSArray *verticalConstraints; @property (nonatomic, strong) NSArray *horizontalConstraints;
我可能建议使用 VFL,它更简洁一点:
- (void)updateViewConstraints { if (self.horizontalConstraints) [self.view removeConstraints:self.horizontalConstraints]; if (self.verticalConstraints) [self.view removeConstraints:self.verticalConstraints]; [super updateViewConstraints]; NSDictionary *views = NSDictionaryOfVariableBindings(_button1); NSDictionary *metrics = nil; if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) { metrics = @{@"left" : @100, @"right" : @100, @"top" : @200, @"bottom" : @100}; _button1.backgroundColor = [UIColor redColor]; } else{ metrics = @{@"left" : @200, @"right" : @200, @"top" : @50, @"bottom" : @50}; _button1.backgroundColor = [UIColor blueColor]; } self.horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(left)-[_button1]-(right)-|" options:0 metrics:metrics views:views]; self.verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(top)-[_button1]-(bottom)-|" options:0 metrics:metrics views:views]; [self.view addConstraints:self.horizontalConstraints]; [self.view addConstraints:self.verticalConstraints]; }
关于ios - 自动布局问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20331148/