iOS开发tips-UIScrollView的Autlayout布局

UIScrollViewj尽管继承于UIView,但它是一个相对比较特殊的视图,特别是当它遇到了AutoLayout之后。在UIScrollView中使用AutoLayout的目的除了使用相对约束确定子控件的位置和大小外,更重要的是如何自动计算出UIScrollView的contentSize(关于使用UIScrollView并且最终手动指定contentSize的AutoLayout用法不再今天讨论之列,严格意义上来说这也不是一种真正的UIScrollView的AutoLayout应用)。

UIScrollView的特殊之处

所谓UIScrollView的特殊之处就在于当它遇到了AutoLayout之后其contentSize的计算规则有些特殊。首先contentSize是根据子视图的leading/trailing/top/bottom进行确定的,而子视图的位置约束又必须依赖于UIScrollView来确定。这就有点类似于前面UICollectionView自适应高度文章中提到的:UICollectionViewCell的大小计算就是计算contentView的大小,而contentView的大小计算依赖于子视图的leading/trailing/top/bottom,子视图的位置约束又依赖于contentView,此时只要子视图存在固有尺寸(intrinsicContentSize)或者指定了尺寸又设置了leading/trailing/top/bottom,AutoLayout布局引擎即可计算出contentView的大小。
再回到AutoLayout,其实它的contentSize计算原理和UICollectionViewCell自适应很是类似,只是UIScrollView内部并没有一个contentView的东西(但是可以想象其存在,方便后面的理解,不过要清楚UIScrollView滚动的本质并非包含一个contentView而是通过bounds和frame坐标体系转换来实现的),只要设置子视图的leading/trailing/top/bottom(通常是通过edges=0让子视图上下左右间距都为0保证整个视图都在UIScrollView可视范围之内),然后通过设置size(width/height)约束确定子视图大小进而由AutoLayout反向计算出UIScrollView的contentSize。
假设A是UIScrollView(蓝色)、B是子视图1(绿色)、C是子视图2(绿色)、D是contentSize的计算区域(灰色,事实上它不存在),要想让cotentSize可以自动计算只需要确定B、C上下左右布局间距,然后再指定B、C间距和尺寸之后AutLayout既可以自动推断出contentSize的大小,原理如下图(下图布局类似于下面Demo3):

demo

demo1 单个子视图布局

对于单个子视图布局比较简单,只要设置leading/trailing/top/bottom,再设置子视图的size(width/height)即可,当然如果子视图存在固有尺寸并且想要使用固有尺寸的话,则这一步也可以省略。例如下面demo中演示了一个UIScrollView包含一个UIImageView子视图的图片查看界面。在下面的布局中仅仅设置了UIImageView上下左右边距,而UIImageView存在固有尺寸,因此整个布局就相当简单了(AutoLayout布局使用SnapKit库)。

    class ImageViewController: UIViewController {   
        override func viewDidLoad() {
            super.viewDidLoad()

            self.view.addSubview(self.scrollView)
            self.scrollView.addSubview(self.imageView)
            self.scrollView.snp.makeConstraints { (make) in
                make.edges.equalTo(0.0)
            }

            self.imageView.snp.makeConstraints { (make) in
                // 下面的约束用于确定contentSize的边距约束(leading/trailing/top/bottom)
                // 而由于UIImageView和UILabel、UIButton一样存在固有尺寸(intrinsicContentSize),因此不需要其他size约束就可以计算出contentSize大小
                make.edges.equalTo(0.0)
            }

        }

  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值