关于Autolayout制作动画的坑

字数 320阅读 1132

需求

一直以来iOS的 Autolayout 都是一个很不错的功能,结合第三方 Masonry 可以节省很多工作成本。但是如果使用 Autolayout 来制作动画,那么就需要注意一下。不然就会像我一样,遇坑踩坑,越陷越深。

使用xib实现动画

使用情景:自定义一个UIView ViewA,实现由下往上弹窗效果。

效果如下


效果图

假如我们是使用xib创建自定义弹窗视图,一般我们都会在xib上做好了约束的条件,之后在.m文件里面实现视图的初始化操作。

自定义UIView

实现动画的原则是,在ViewA执行动画之前,需要将ViewA最终约束条件设置好,之后在执行动画代码块里面只需要调用layoutIfNeeded即可。

另外调用layoutIfNeeded方法的对象必须是ViewA的父视图,不然会出现ViewA的子视图跟着执行动画的情况。

如下面的代码中,ViewA的父视图就是window,所以调用layoutIfNeeded方法的对象是window

- (instancetype)init {
    self = [[[NSBundle mainBundle] loadNibNamed:@"DDJoinView" owner:self options:nil] lastObject];
    if (self) {
        self.frame = CGRectMake(0, kScreenHeight, kScreenWidth, 195);
    }
    return self;
}
- (void)show {
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    _bgView = [[UIButton alloc] init];
    _bgView.backgroundColor = UIColorHex(0x000000);
    _bgView.alpha = 0.25;
    _bgView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
    [_bgView addTarget:self action:@selector(close:) forControlEvents:UIControlEventTouchUpInside];
    [window addSubview:_bgView];
    [window addSubview:self];
    [self mas_updateConstraints:^(MASConstraintMaker *make) {
        (void)make.left;
        (void)make.centerX;
        make.height.offset(195);
        make.bottom.offset(0);
    }];
    [UIView animateWithDuration:0.3f animations:^{
        [window layoutIfNeeded];
    }];
}
#pragma mark - 關閉
- (void)close:(id)sender {
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    [self mas_updateConstraints:^(MASConstraintMaker *make) {
        (void)make.left;
        (void)make.centerX;
        make.height.offset(195);
        make.bottom.offset(195);
    }];
    [UIView animateWithDuration:0.3f animations:^{
        [window layoutIfNeeded];
    } completion:^(BOOL finished) {
        for (UIView *v in [self subviews]) {
            [v removeFromSuperview];
        }
        [self removeFromSuperview];
        [_bgView removeFromSuperview];
    }];
}

总结

//...
//执行下面动画前,设置自定义view的最终位置的约束条件
//...
[UIView animateWithDuration:0.3f animations:^{
        [xxx layoutIfNeeded];
    } completion:^(BOOL finished) {
        //do something
}];

再一次感谢您花费时间阅读这篇文章!

微博: @Danny_吕昌辉
博客: SuperDanny

推荐阅读更多精彩内容