原理
使用autolayout布局cell的sub view,同时,利用UIView的systemLayoutSizeFittingSize方法,让View自动计算自身的高度。
UIView本身在layoutSubviews时,会计算自身所有的subview的fram等。但systemLayoutSizeFittingSize又不仅仅使用layoutSubviews来衡量sub view的frame信息。
例子
要实现下面这样的cell,cell的高度根据内容的多少,自动改变高度。甚至于根据布局的变化,自动的计算自身的高度。
一般来说,要计算cell的高度,我们根据cell内容的各种信息,可以手动计算出来。但是这种方法累加各个sub view,获取最终cell高度的方法有几个坏处。
计算繁琐。如果cell的sub view特别多,布局复杂,则计算起来要处理各种场景逻辑,工作量繁重。
容易产生错误。复杂的逻辑就容易产生错误。特别是加上适配各种设备,则让人发狂崩溃。
系统兼容性不好。随着ios系统的升级,特别是每年苹果都有新的设备发售。要处理这些工作,需要时不时进行升级适配。
所以,如何利用ios系统的api,自动的计算cell的高度,是最理想的情况。
自ios6以后,系统api提供了systemLayoutSizeFittingSize方法,能够计算UIView的显示尺寸。
要实现如下这样的效果图:
当内部文字变化的时候,cell会自动的计算自身高度。如下代码:
如上图_contentBkg为文字所在的背景。当文字增多时,背景和cell同时自动增加高度。编写的autolayout代码使用masonry。如下:
其中方框内代码获取到布局后的cell的高度。关键代码在120-132行。_content为文字所在的label,在alloc的时候,绑定了一个preferredMaxLayoutWidth,该值限制了label的最大宽度。当文字在label内的展现超出这个值后,会自动的截断或者换行,为了时label换行,需要设置以下连个属性:
_content.numberOfLines=0;
_content.lineBreakMode=NSLineBreakByWordWrapping;
布局的时候,需要把文字的top和bottom与父视图绑定,以便于系统根据label高度,来推测super view的高度。(这个高度的绑定,如果直接用layoutIfNeeded,然后来获取cell contentview的高度,自动布局会报约束冲突的错误。而使用systemLayoutSizeFittingSize不会报错,所以说systemLayoutSizeFittingSize不仅仅是调用layoutIfNeeded来计算subview的位置信息,应该是同时设置了父视图的frame属性由sub view推导获取)。
如果不采用systemLayoutSizeFittingSize来获取contentview的高度,则需要把contentview的bottom和sub view解除约束。同时使用layoutIfNeeded,来计算sub view的最大y值,由此来获取content view的高度。也是一种方法。
网友评论