使用约束移动按钮朝向目标,没有反应?

时间:2014-12-21 20:22:27

标签: ios objective-c xcode autolayout constraints

我希望红色按钮能够朝向第二个按钮的前导位置进行动画处理:

enter image description here

一些例子展示了如何用数字改变“常数”,但我想自动置于第二个按钮的前导位置。

我尝试了这个,但红色按钮没有移动,动画日志正确调用:

- (void)updateConstr{

    NSLayoutConstraint *newLeading = [NSLayoutConstraint
                                                  constraintWithItem:self.redB
                                                  attribute:NSLayoutAttributeLeading
                                                  relatedBy:NSLayoutRelationEqual
                                                  toItem:self.secondButton
                                                  attribute:NSLayoutAttributeLeading
                                                  multiplier:1.0
                                                  constant:0.0f];

    self.leadingConstraint = newLeading;//is an IBOutlet pointing on the constraint (see the image)
    [self.redB setNeedsUpdateConstraints];
    [UIView animateWithDuration:0.5 animations:^{
        [self.redB layoutIfNeeded];
        NSLog(@"animations");//is called, but the red button does not move
    }];
}

- (IBAction)firstAction:(id)sender { //after a click on button "one"
    NSLog(@"firstAction");
    [self updateConstr];
}

2 个答案:

答案 0 :(得分:1)

在这种情况下我通常做的是以下内容。

为场景添加两个约束。一个在按钮和“一个”标签之间左对齐的地方。第二个,它在按钮和“第二个”标签之间左对齐(即两个值都为0)。这些约束最初会相互冲突,这很好。

IBOutlets添加到NSLayoutConstraints的视图控制器中,并将我们创建的两个约束分配给IBOutlets

将初始条件的约束优先级设置为999(即左对齐约为“1”的约束应为999)。将目标约束上的约束优先级设置为998(即,按钮与“秒”之间左对齐的约束是998)。您现在将看到这些约束将不再发生冲突。这是因为一个约束的优先级会覆盖另一个约束。

你可能会看到现在的发展方向。因此,当您想要在约束之间设置按钮动画时,请交换优先级并设置动画!

代码:

@interface MyViewController ()
     @property (nonatomic, weak) NSLayoutConstraint* constraint0;
     @property (nonatomic, weak) NSLayoutConstraint* constraint1;
@end

- (void)someMethodWhereIWantToAnimate
{
     NSInteger temp = constraint0.priority;
     constraint0.priority = constraint1.priority;
     constraint1.priority = temp;

     [UIView animateWithDuration:1.0 animations:^{
         // Simplest is to use the main ViewController's view
         [self.view layoutIfNeeded];
     }];
}

答案 1 :(得分:1)

必须这样做:

- (void)updateConstr{

    NSLayoutConstraint *newLeading = [NSLayoutConstraint
                                      constraintWithItem:self.redB
                                      attribute:NSLayoutAttributeLeading
                                      relatedBy:NSLayoutRelationEqual
                                      toItem:self.secondButton
                                      attribute:NSLayoutAttributeLeading
                                      multiplier:1.0
                                      constant:0.0f];

    [self.redB.superview removeConstraint: self.leadingConstraint];
    [self.redB.superview addConstraint: newLeading];
    self.leadingConstraint = newLeading;

    [UIView animateWithDuration:0.5 animations:^{
        [self.redB layoutIfNeeded];
    }];
}