Auto Layout 常见问题汇总

1. 多个view等间距分布

这个问题较为常见,也比较好解决,根据官方文档中的spacer view的概念,主要是利用已经hidden的view来实现,设置这些spacer view的宽或高属性相等即可巧妙实现。spacer view结合auto layout使用,灵活使用可以解决大部分的UI问题。
参考资料:
  • http://stackoverflow.com/questions/13075415/evenly-space-multiple-views-within-a-container-view
  • https://github.com/mayoff/stackoverflow-17089427-auto-layout-equal-spacing
  • http://stackoverflow.com/questions/17089427/ios-autolayout-vertically-equal-space-to-fill-parent-view


2.  View的hidden设置为YES,间距不变的问题

UIView有一个很有意思的特性,即使UIView就算hidden为YES,它的宽高仍然是参加auto layout的,并且frame一般是不会变化,除非对于类似UILabel这样已经重写了intrinsic content size的控件。这也是我们可以非常方便使用spacer view的原因。
这个特性给我们带来方便的同时,也给我们带来了一些问题,我在实际开发中常遇到一个情况,就是根据服务器的返回的数据展示不同的UI,比如我们经常需要实现下面这两种情况,图来自stackoverflow。

Auto Layout 常见问题汇总_第1张图片
或者
Auto Layout 常见问题汇总_第2张图片

有时候根据各种数据和产品需求的不同,我们希望可以通过控制某个UIView的展示与否,然后调整其他view的frame。可我发现虽然设置UIView的hidden为YES,但是UIView的frame所占的空间仍然在,留有一片空白。

解决方式有两种:
(1) 通过NSPredicate来筛选出对应的NSLayoutConstraint对象,然后修改其中的对应的值,原理可以参考:http://stackoverflow.com/questions/13857115/getting-an-existing-nslayoutconstraint-for-the-width。github上的开源实现:https://github.com/damienromito/UIView-UpdateAutoLayoutConstraints,https://github.com/depth42/AutolayoutExtensions

参考资料以及github开源实现:
  • http://stackoverflow.com/questions/18065938/how-to-use-auto-layout-to-move-other-views-when-a-view-is-hidden
  • http://stackoverflow.com/questions/22384927/hide-autolayout-uiview-how-to-get-existing-nslayoutconstraint-to-update-this-o/
  • https://github.com/damienromito/UIView-UpdateAutoLayoutConstraints
  • https://github.com/depth42/AutolayoutExtensions
  • http://stackoverflow.com/questions/13857115/getting-an-existing-nslayoutconstraint-for-the-width
  • http://stackoverflow.com/questions/19561269/autolayout-with-hidden-uiviews

(2) 第二种是我自己的一种实现,通过继承实现UIView,并设置这个UIView的intrinsicContentSize方法来实现,优点是可以不用通过NSLayoutConstraint来约束spacer view的size,直接设置这个view的size即可,这样使用起来会比较灵活方便。不足是使用的时候需要使用起来稍微麻烦,这个类后续我还会扩展一下,只是通过autolayout来直接获取view的size,这样使用起来会更加灵活一些。

#pragma mark - spacer view

@interface AutolayoutFixSizeSpacerView : UIView

@property ( nonatomic , assign ) CGSize spacerSize;

@end

@implementation AutolayoutFixSizeSpacerView

- (
void )setHidden:( BOOL )hidden
{
    [
super setHidden :hidden];
   
    [
self invalidateIntrinsicContentSize ];
}

- (
CGSize )intrinsicContentSize
{
   
// 不能通过给 Spacerview 的子 view 添加约束来限定 SpacerView 的宽高,否则, intrinsicContentSize 将会无效
   
// 详细解释,可以查看 UIView 的头文件中关于 intrinsicContentSize 的说明
   
if ( self . hidden ) {
       
return CGSizeZero ;
    }
else {
       
return self . spacerSize ;
    }
}

- (
void )setSpacerSize:( CGSize )spacerSize
{
   
_spacerSize = spacerSize;
    [
self invalidateIntrinsicContentSize ];
}

@end


3. 设置View的宽高比例

这个思路较为简单,其实就是为宽和高属性添加约束即可,不赘述,参考如下:
  • http://stackoverflow.com/questions/14188187/auto-layout-constraint-how-to-make-a-view-maintains-its-width-height-ratio-when
  • http://stackoverflow.com/questions/19571226/xcode-5-autolayout-and-making-uiviews-width-equal-to-height
  • http://stackoverflow.com/questions/25766747/emulating-aspect-fit-behaviour-using-autolayout-constraints-in-xcode-6/25768875#25768875


4. UITableviewCell与auto layout结合

raywender上面有一个非常好的教程,基本上就可以说完了,http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout


5. UILabel使用autolayout并支持多行显示

设置translatesAutoresizingMaskIntoConstraints为 NO,设置numberOfLines==0(默认为1),并且在适当的地方设置 preferredMaxLayoutWidth 这个值


6. UIButton使用Autolayout的时候设置inset的问题

使用titleEdgeInsets会导致titleLabel的frame变小,导致title无法显示完全,更改为设置contentEdgeInset即可。


你可能感兴趣的:(Auto Layout 常见问题汇总)