iOS 知识点-Masnory约束UIScrollerView的坑以及用Masonry实现动画

Masnory约束UIScrollerView

直接用Masonry对scrollView进行约束,scrollView是不会滑动的,因为确定不了contentSize。那么为什么继承UIScrollerView的UITableView和UICollectionView没有这种问题呢,可以发现他们的cell都有一个叫contentView的子视图,我们自己添加的view 也都是加到contentView上边的。

所以解决思路:给scrollView添加唯一的子视图contentView,通过拉伸子视图的size来确定scrollView的contentSize。

给contentView设置约束,注意:make.width.equalTo(self);这个约束必须要添加

        self.contentView = [[UIView alloc] init];
        self.contentView.backgroundColor = [UIColor clearColor];
        [self addSubview:self.contentView];
        [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self);
            //因为上面的宽高是相对于contentSize的  所以为0  这里需要设置contentView的宽度约束后  scrollView的contentSize.width就会拉伸
            make.width.equalTo(self);
        }];

还要注意一点,在对contentView的最后一个子视图添加约束的时候要加上make.bottom.equalTo(-20);这样contentView才能确定scrollerView的contentSize,iOS8之后的tableView的cell高度自适应,设置tableView.estimatedRowHeight = 100;//一个估算值 之后,也是必须要对cell的子视图的最后一个view加上距离底部的约束,才能实现cell高度自适应

/// 说明文字
    UILabel *lable = [UILabel labelWithText:@"使用说明:抵扣券可用于借款时抵扣手续费\n积分可在商城中兑换礼品或者话费" textFont:WGiveWidth(11) textColor:[LKTool colorWithHexString:@"#b996d9"] frame:CGRectZero];
    [self.scrollerView.contentView addSubview:lable];
    lable.textAlignment = 1;
    lable.numberOfLines = 0;
//    [lable setRowSpace:5];
    [lable mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(btn.mas_bottom).offset(10);
        make.width.equalTo(SCREEN_WIDTH);
        make.centerX.equalTo(btn);
        // 必须加上这个约束 这样contentView才能确定scrollerView的contentSize
        make.bottom.equalTo(-20);
    }];

Masnory实现动画效果

在iOS开发中使用frame来动画更新控件frame是再熟悉不过的了:

[UIView animateWithDuration:0.5 animations:^{
    view.frame = CGRectMake();
}];

但使用Masonry后,使用如下代码来更新控件约束后,但无法看到控件位置更新的动画:

[UIView animateWithDuration:0.5 animations:^{
    [view mas_updateConstraints:^(MASConstraintMaker *make) {
        make.right.mas_equalTo();
    }];
}];

正确的姿势:

        [self.alertView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self);
        }];

        // 告诉self.view约束需要更新
        [self setNeedsUpdateConstraints];
        // 调用此方法告诉self.view检测是否需要更新约束,若需要则更新,下面添加动画效果才起作用
        [self updateConstraintsIfNeeded];

        [UIView animateWithDuration:0.1 animations:^{
            //使约束立即生效
            [self layoutIfNeeded];
        } completion:^(BOOL finished) {
             // 动画结束之后处理
        }];

后来发现不用调用setNeedsUpdateConstraintsupdateConstraintsIfNeeded动画也是会生效的。

效果图:

效果图.gif

推荐阅读更多精彩内容