自动版式,约束和动画 [英] AutoLayout, Constraints and Animation

查看:99
本文介绍了自动版式,约束和动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设我有这个的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 此按钮,用户点击应该移动到视图的右下角。我们可以很方便地使用两个约束定义按钮,底部布局引导,并从该按钮,空间(尾随空间)和视图的右边缘之间的底部空间。

Okay now let's assume that when the user click on that UIButton the button should move to the bottom-right corner of the view. We can easily use two constraints defining bottom space between the button and the bottom layout guide and right space (trailing space) from the button and the right edge of the view.

这是问题的的UIButton 已经有两个约束(左/顶)和两个约束上定义的宽度和高度,所以我们不能添加两个新的约束,因为他们将与其他的冲突。

The problem it's that the UIButton already had two constraints (left/top) AND two contraints defining its width and its height so we can't add two new constraints because they would conflict with the other ones.

简单而常见的情况为动画场景,但它引起了我一些问题。想法?

Simple and common situation for an animation scenario, but it causing me some problems. Ideas?

修改

当用户点击了的UIButton ,我需要一个按钮:

When the user taps on the UIButton, I need that the button:


  1. 其标题改为二

  2. 等待1秒,并移动到右下角(除去顶部和左边缘的限制,并添加底部和右边缘约束)

  3. 改变它的标题改为三

  4. 等待1秒,并移动到右上角(除去底部边缘约束
    并添加上边距约束)

我是认真必然要使用这个凌乱code?

Am I seriously bound to use this messy code?

@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

Serious? :D

推荐答案

删除左侧和顶部的限制,加上底部和右侧的限制,然后调用layoutIfNeeded在动画块动画到新的位置。在第二种方法在code,MOVE2可以嵌入在move1完成块,但我觉得如果你保持在不同的方法两个动作更易于阅读(它确实必要增加其他属性,bottomCon的):

Delete the left and top constraints, add the bottom and right constraints, then call layoutIfNeeded in an animation block to animate to the new position. The code in the second method, move2 could be embedded in the completion block of move1, but I find it easier to read if you keep the two moves in separate methods (it does necessitate the addition of another property, bottomCon):

- (IBAction)move1:(UIButton *)sender {
    [sender setTitle:@"Second" forState:UIControlStateNormal];
    [sender layoutIfNeeded];
    [self.view removeConstraints:@[self.leftCon,self.topCon]];
    self.bottomCon = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:0 toItem:self.button attribute:NSLayoutAttributeBottom multiplier:1 constant:20];
    [self.view addConstraint:self.bottomCon];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeRight relatedBy:0 toItem:self.button attribute:NSLayoutAttributeRight multiplier:1 constant:20]];
    [UIView animateWithDuration:1 delay:1.0 options:0 animations:^{
        [self.view layoutIfNeeded];
    } completion:^(BOOL finished) {
        [sender setTitle:@"Third" forState:UIControlStateNormal];
        [self move2];
    }];
}

-(void)move2 {
    [self.view removeConstraint:self.bottomCon];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTop relatedBy:0 toItem:self.button attribute:NSLayoutAttributeTop multiplier:1 constant:-20]];
    [UIView animateWithDuration:1 delay:1.0 options:0 animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];
}

这篇关于自动版式,约束和动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆