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。
或者
有时候根据各种数据和产品需求的不同,我们希望可以通过控制某个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即可。