iOS snapkit UIScrollView 自适应布局, UIScrollView 嵌套 UICollectionView

一.比较正规的使用方式

类似于 storyboard ,在UIScrollView上添加一个充满自己的ContainerView

场景分析

在实际开发中遇到UIScrollView的场景大概分为两类: 超过一个竖屏的信息展示 和 轮播图,以少数派App做个例子

iOS snapkit UIScrollView 自适应布局, UIScrollView 嵌套 UICollectionView_第1张图片

少数派.gif

技术难点

通常来说,UIScrollView的布局 有两种方法:

  • StoryBoard + AutoLayout的方式
  • 代码 + SnapKit布局的方式 进行

不管我们采取哪种布局技术,如果我们直接在UIScrollView中添加子视图,然后给子视图相对于UIScrollView添加约束,会发现子视图是无法显示的,这是什么原因呢?

其实是因为: UIScrollView的leading/trailing/top/bottom是相对于自己的ContentSize来说的,而不是Frame; 而在给所有子视图添加完视图前ContentSize还不确定,我们这时候又给子视图添加约束到ContentSize,相互依赖,不就成了蛋生鸡,鸡生蛋的问题了。

解决方案

我们可以给UIScrollView添加一个充满自己的ContainerView,然后我们所有子视图的布局相对于这个ContainerView就好了; 同时,只要确定了ContainerView的尺寸,也就确定了UIScrollView的ContentSize

干起来

我们通过SnapKit + 代码的方式给一个垂直滚动的UIScollView加约束来做例子,其他情况原理都是类似的。

  • Step1: 给UIScollView添加约束,没什么可说的

 

    view.addSubview(scrollView)
    scrollView.snp.makeConstraints { (make) in
        make.edges.equalToSuperview()
    }
  • step2 : 给UIScollView添加一个充满他的ContainerView(重要)
    注意:ContainerView给定了宽度,即UIScollView的ContentSize的宽度确定了,还需要确定高度

 

    scrollView.addSubview(containerView)
    containerView.snp.makeConstraints { (make) in
          make.edges.equalToSuperview()
          make.width.equalTo(ScreenWidth)
    }

Step3: 在ContainerView中添加子视图

 

    //add 5 orange view
        for i in 0..<5 {
            let orangeView = UIView()
            orangeView.backgroundColor = #colorLiteral(red: 0.9372549057, green: 0.3490196168, blue: 0.1921568662, alpha: 1)
            containerView.addSubview(orangeView)
            orangeView.snp.makeConstraints({ (make) in
                make.left.right.equalTo(containerView)
                make.height.equalTo(orangeViewGap)
                
                if i == 0 {
                    make.top.equalTo(containerView.snp.top).offset(orangeViewGap)
                } else if let previousView = containerView.subviews[i-1] as? UIView{
                    make.top.equalTo(previousView.snp.bottom).offset(orangeViewGap)
                }
                
                if i == 4 {
                    containerView.snp.makeConstraints({ (make) in
                        make.bottom.equalTo(orangeView.snp.bottom).offset(orangeViewGap)
                    })
                }
            })
        }

上面代码中,第一个View很简单,关键是最后一个子视图,一定要加好最后一个子视图到ContainerView的间隔,即我们确定了ContainerView的高度,那么我们就确定了UIScrollView的ContentSize的高度,到此,完成整个布局过程; 核心代码都在上面。
最终,完成效果如下:

iOS snapkit UIScrollView 自适应布局, UIScrollView 嵌套 UICollectionView_第2张图片

ScrollView.gif



作者:死神一护
链接:https://www.jianshu.com/p/a969962e5bc6
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

UIScrollView 嵌套 UICollectionView,UICollectionView 高度自适应

先给 UICollectionView 一个 height

collectionView.snp.makeConstraints { (make) in
            make.top.equalTo(topLabel.snp.bottom)
            make.left.equalTo(18)
            make.right.equalTo(-18)
            make.height.equalTo(0)
        }

在获取数据源刷新 collectionView 后,利用 UIcollectionView 的 contentSize 更新collectionView 高度

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
            collectionView.snp.updateConstraints { (make) in
                make.height.equalTo(collectionView.contentSize.height)
            }
        }

 

二. 不添加 ContainerView

1.使用代码布局scrollView时,是不能手动设置contentSize,他的contentSize是会自己根据子控件来自动计算

2.设置子控件时候,一定要直接了当的设置子控件的大小(width  height),只有这样,scrollview才会知道自己的contentSize是多大

3.用到SnapKit第三方
 

        view.addSubview(scrollView)
        scrollView.addSubview(topLabel)
        scrollView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        topLabel.snp.makeConstraints { (make) in
            make.top.equalTo(50.0)
            make.left.equalTo(0)//这里一定要写具体值,
            make.width.equalTo(view)//这里可以写具体值,或者view 但是不能写scrollView
            make.height.equalTo(21)
        }

 

你可能感兴趣的:(iOS)