ios的布局:
1.frame的布局:
a.用纯代码的,我们可以是直接设置Frame的
b.首先xib中随便拖入一个控件,其实拖入的是就有一个位置和大小,其实已经设置好了frame.
2.autoresizing,这个玩意并不直接是一种全新的布局,他的出现只是一个Frame的补充.
他用于解决的问题主要是通过设置子控件的一些属性,让子控件跟着父控件做一些调整.不适用兄弟控件之间的东西,所有他对布局有补充,但是非常有限.
首先他这个东西生效有一个开关,translatesAutoresizingMaskIntoConstraints 决定是否生效,还有就是一个autoresizingMask决定了哪些方面要跟着父控件进行调整.
UIViewAutoresizingNone view的frame不会随superview的改变而改变
UIViewAutoresizingFlexibleLeftMargin 自动调整view与superview左边的距离保证右边距离不变
UIViewAutoresizingFlexibleWidth 自动调整view的宽,保证与superView的左右边距不变
UIViewAutoresizingFlexibleRightMargin 自动调整view与superview右边的距离保证左边距不变
UIViewAutoresizingFlexibleTopMargin 自动调整view与superview顶部的距离保证底部距离不变
UIViewAutoresizingFlexibleHeight 自动调整view的高,保证与superView的顶部和底部距离不变
UIViewAutoresizingFlexibleBottomMargin 自动调整view与superview底部部的距离保证顶部距离不变
特别需要注意的是在xib中控件一般拖入xib中,默认是autoresize是选择的,如果我做任何选择,autoresize默认是有一些选项,需要根据自己的选择去做设置.但是当我们去给这个拖入的控件设置约束时,autoresize就会自动取消了.我们使用的自动布局框架masonry也是这样的,当我们开始对某个控件设置约束时,他也会设置translatesAutoresizingMaskIntoConstraints 为NO,禁用autoResize.
3.autoLayout
可以通过xib设置约束,也可以通过masonry设置约束. autoResize和autolayout只能二选一.
几个重要的API
intrinsicContentSize[固有内容大小] 主要是用在UILabel,UIButton里面,他们里面一般不添加子控件,然后label可以根据里面的文字就可以确定UIlabel的大小,UIButton可以根据里面的title或者image确定控件的大小.
但是有些 view 不包含 content,譬如UIView,这种 view 被认为「has no intrinsic size」,它们的intrinsicContentSize返回的值是(-1,-1)。
还有一种 view 虽然包含 content,但是intrinsicContentSize返回值也是(-1,-1),这类 view 往往是UIScrollView的子类,譬如UITextView,它们是可滚动的,因此 auto layout system 在对这类 view 进行布局时总会存在一些未定因素,Cocoa 干脆让这些 view 的intrinsicContentSize返回(-1,-1)。
preferredMaxLayoutWidth :主要是用来限制多行文字的宽度,比方说显示多行文字的label控件的位置最多可以到300宽度,但是如果你设置preferredMaxLayoutWidth = 200,那么label 的内容的宽度就只到200,然后换行显示.
sizeThatFits:方法和 sizeToFit 方法
对于UILabel 如果设置了位置,设置了文字,就可以通过intrinsicContentSize方法从系统获取并设置,如果是多行文字也可以设置preferredMaxLayoutWidth来获取文字的高度,也可以通过sizeToFit.
sizeThatFits:size 后面的size 如果和preferredMaxLayoutWidth值设定的一样,那么用sizeThatFits:算出来的尺寸就和 使用preferredMaxLayoutWidth设定出来的结果一样.
总结:对于一般的button,Label设置了文字或者图片后一般不用设置宽度,高度,系统会根据intrinsicContentSize,多行文字再加一个preferredMaxLayoutWidth最大的宽度就可以搞定.
而sizeThatFits:非他不可的场所在比方UITextView这种控件,可以设定根据后面跟着设定的CGSize()设定的宽度来计算最佳的contentview尺寸,而非本身控件的尺寸,当然你可以用sizeThatFits:来算单行多行文字,或者button的尺寸,不过有点大材小用的感觉(因为他们可以用最简单的intrinsicContentSize来获取尺寸).
而sizeThatFits 和 sizeToFit差别很简单,前面只是算出来一个size,并不给控件设置这个size,后者是算出来最佳的size并给他设置.
最后一个东东:
systemLayoutSizeFittingSize:
对于上面几个东西,如果在一个View里面设置好上面的约束.怎么算设置好约束呢?
1.对于单行的label 设置文字
2.对于按钮设置好图片和文字
3.多行文字设置好preferredMaxLayoutWidth
4.对于继承了UIScrollview这类控件用sizeThatFits:来计算好内容的尺寸,设置尺寸,或者直接设置你想设置的宽高就可以
这些做到就算设置好了上面的约束,约定最上面的控件距离背景view的距离,最下面的控件距离背景view的高度,我们就可以正确的显示背景View,在系统显示时我们就可以正确获取它的高度.但是如果我们这个View没有显示前就拿到他的尺寸,有什么办法呢?
我们很容易在自己计算tableView时经常有这样的需求,需要在下面的方法返回cell的高度,做法是什么呢?
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
做法就是使用systemLayoutSizeFittingSize:来拿到他的高度.当然还有一种笨办法是自己一个一个算加起来,当然还可以让他自动计算.
我们这里讨论的是用
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
cell 可以从下面的方法中将cell保存起来,然后在调用heightForRow时返回用上面 systemLayoutSizeFittingSize来获取cell的高度.注意一点的时,最好给cell设置一个估算高度,防止heightForRow一开始就被调很多次去显示滑动条的的高度,这样可以优化性能.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath