假设我有这个 UIView
:
以及这些相对约束:
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *leftMarginConstraint;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topMarginConstraint;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *widthConstraint;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *heightConstraint;
假设用户单击UIButton
时,按钮应该移动到视图的右下角。我们可以轻松使用两个约束来定义按钮和底部布局指南之间的底部空间和按钮与视图右边缘之间的右侧空间(尾随空间)。
问题在于 UIButton
已经有了两个约束(左/上),以及两个定义其宽度和高度的约束,因此我们不能添加两个新的约束,因为它们会与其他约束冲突。
对于动画场景来说,这是一个简单而常见的情况,但它给我带来了一些问题。有什么好的想法吗?
编辑
当用户点击UIButton
时,我需要按钮执行以下操作:
- 将标题更改为“Second”
- 等待1秒钟并移动到右下角(删除顶部和左侧边距约束,并添加底部和右侧边距约束)
- 将标题更改为“Third”
- 等待1秒钟并移动到右上角(删除底部边距约束并添加顶部边距约束)
我是否必须使用这个混乱的代码?
@implementation ViewController
{
NSLayoutConstraint *_topMarginConstraint;
NSLayoutConstraint *_leftMarginConstraint;
NSLayoutConstraint *_bottomMarginConstraint;
NSLayoutConstraint *_rightMarginConstraint;
}
- (IBAction)buttonPressed:(id)sender
{
UIButton *button = sender;
// 1.
[sender setTitle:@"Second" forState:UIControlStateNormal];
// 2.
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[button removeConstraints:@[self.leftMarginConstraint, self.topMarginConstraint]];
_bottomMarginConstraint = [NSLayoutConstraint constraintWithItem:self.view
attribute:NSLayoutAttributeBottom
relatedBy:0 toItem:button
attribute:NSLayoutAttributeBottom
multiplier:1
constant:20];
[self.view addConstraint:_bottomMarginConstraint];
_rightMarginConstraint = [NSLayoutConstraint constraintWithItem:self.view
attribute:NSLayoutAttributeRight
relatedBy:0 toItem:button
attribute:NSLayoutAttributeRight
multiplier:1
constant:20];
[self.view addConstraint:_rightMarginConstraint];
[UIView animateWithDuration:1 animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
// 3.
[sender setTitle:@"Third" forState:UIControlStateNormal];
// 4.
double delayInSeconds = 1.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[button removeConstraint:_bottomMarginConstraint];
_topMarginConstraint = [NSLayoutConstraint constraintWithItem:self.view
attribute:NSLayoutAttributeTop
relatedBy:0 toItem:button
attribute:NSLayoutAttributeTop
multiplier:1
constant:20];
[UIView animateWithDuration:1 animations:^{
[self.view layoutIfNeeded];
}];
});
}];
});
}
认真的吗? :D
UIViewAlertForUnsatisfiableConstraints:
? - Glavid