Autolayout小结(二)

Autolayout小结(二)

Autolayout小结(一)中介绍了在Autolayout学习中一些基本的注意点,本文会针对一些布局上常见的问题进行分析。ide

  1. 如何自动适应cell的高度布局

  2. 如何在ScrollView中使用Autolayout学习

  3. 使用Autolayout作动画测试

  4. Autolayout在IOS6上的坑动画

1. 如何自动适应cell的高度

在IOS的布局中,计算和适应cell的高度是个经典的问题, 在frame时代,咱们都知道用sizeWithFont: 先计算出文字的高度,而后经过计算得出cell的高度,而后赋予heightForRow:ui

那在Autolayout时代如何计算cell的高度呢?由于sizeWithFont:方法已经不太实用了。其实Autolayout不但更简单,还能够不用写过多的计算代码达到自适应高度。spa

理论上是能够经过已知的完整的Constraints和view的属性来计算高度的,咱们能够经过systemLayoutSizeFittingSize:方法来获取计算出来cell的size,咱们知道cell的高度须要在tableView的代理方法tableView:heightForRowAtIndexPath:中实现的,那么咱们考虑从如下两点来作:设计

  • 经过建立一个额外的cell专门用来计算其高度3d

  • 由于计算须要布局,因此尽可能让其只计算一次,计算完能够将高度保存起来代理

基于这两个要点,咱们能够尝试以下(伪代码):

- (CGFloat)autoAdjustedCellHeightAtIndexPath:(NSIndexPath *)indexPath inTableView:(UITableView *)tableView {

    

    CGFloat cellHeight = [self cellHeightAtIndexPath:indexPath];

    if (cellHeight > 0) {

        return cellHeight;

    } else {

        //此方法建立用于自适应的cell, 注意建立一个就够了

        UITableViewCell *cell = [self cellForTableViewAutoAdjust];

        

        //更新cell,cellForRow中更新一致

        [self updateCell:cell]

        

        //cell进行layout

        [cell setNeedsUpdateConstraints];

        [cell updateConstraintsIfNeeded];

        cell = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(layoutGuideView.bounds));

        [cell setNeedsLayout];

        [cell layoutIfNeeded];

        

        CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

        

        height += 1.0f;

        //计算完后保存,避免屡次重复计算

        [self saveCellHeight:height forIndexPath:indexPath];

        return height;

    }

}



通过测试,工做良好,在体会到这点好处以后就发现Autolayout的好处了,它实际上是让布局变得简单了。

在完成这个自动适应高度的设计过程当中要注意几点:

  1. cell中的多行UILabel,若是其width不是固定的话(好比屏幕尺寸不一样,width不一样),要手动设置其preferredMaxLayoutWidth。 由于计算UILabel的intrinsicContentSize须要预先肯定其width才行。

  2. 要保证垂直方向上的Constraints理论上能够计算出cell的高度,另:最好调低其中一个Constraint的优先级,避免约束发生冲突

  3. tableView的dequeueReusableCellWithIdentifier取出来的cell若是未用于tableView, 那么它就leak了. 所以用于计算高度的cell不要今后方法获取。

2. 如何在scrollView中使用Autolayout

scrollView比较特殊,由于它有个contentSize的属性。那么在遇到scrollView时,怎么使用Autolayout呢。其实关键点就一点:

ScrollView的contentSize的大小是由其subview的constraints来决定的。

知道这一点其实就够了,那么基于这个特性,在应用的时候要注意哪些呢?

  • 彻底依赖scrollView来计算subview的坐标的Constraints设法不行了,计算条件互相依赖的,常见的如left+right+top+bottom不行了。

  • 要保证contentSize能够经过subview的constraints可以计算出来。

举个栗子:

12345678
[childView mas_makeConstraints:^(MASConstraintMaker *make) {    make.width.mas_equalTo(scrollView.mas_width);  make.height.mas_equalTo(scrollView.mas_height);  make.leading.mas_equalTo(scrollView.mas_leading);  make.top.mas_equalTo(scrollView.mas_top);  make.bottom.mas_equalTo(scrollView.mas_bottom);  make.trailing.mas_equalTo(scrollView.mas_trailing).multipliedBy(1./4.);}];

例子中若是scrollView的size是(100x100), 那么contentSize即为(400x100)

3. Autolayout时的动画

在使用Autolayout时,动画的使用和之前也不一样了,之前咱们是修改frame,如今咱们能够经过修改Constraints, 而后在动画时layoutIfNeeded就好了。

123
[UIView animateWithDuration:0.2 animations:^{    [view layoutIfNeeded];}];

Autolayout有时在动画时候会很方便,由于View之间的坐标是相互影响的,在传统frame中,若是改变一个view的frame,那么可能你要更改不少view的frame,才能让页面显得和谐。在Autolayout中可能只须要修改一个Constraint就能够了,在作动画时会很方便。

4. Autolayout在IOS6上的坑

虽然Autolayout很是强大,可是在刚出现的版本IOS6上,仍是有一些坑的。在IOS6上你会发如今某些系统控件上如: UITableViewCellUITableView 等view上直接添加Constraints会crash。 冲突的Constraints会直接致使crash等。

在strackoverflow有回答上说明了为何UITableViewCell等部分系统控件上添加Constraints会crash, 即UITableViewCell等部分控件的layoutSubviews里面没有执行[super layoutSubviews]

因此想要使用Autolayout的同窗们,若是你要兼容IOS6的话,有些问题仍是要重视的,须要充分的测试哦。

相关文章
相关标签/搜索