本文正在参加「金石计划 . 分割6万现金大奖」

前语

接上一篇,Swift:运用enum抹平数组元素差异,我通过将事务数数据,封装成为一个枚举带参的数组集合,将这个数组作为数据源去驱动UITableView显现页面,并且确保了页面的灵活性。

在留言中,有掘友提出能够通过运用UIScrollView+UIStackView的方法来构建页面。觉得是一个十分不错的点子,所以当即实践了一下。

基本思路

咱们先仍是回到事务数据枚举:

enum BusinessPart {
    case a(APart) 
    case b(BPart) 
    case c(CPart) 
    case d(DPart) 
}

咱们的DataSource数据源是这样的:

let dataSource = [a(aPart), b(bPart), c(cPart), d(dPart)]

如何将一个dataSource变成一个view呢?咱们能够测验在enum BusinessPart增加这样一个分类:

extension BusinessPart {
  var view: UIView {
    switch self {
    case .a(let aPart):
      let aView = AView()
      aview.aPart = aPart
      return aView
    case .b(let bPart):
      let bView = BView()
      bView.bPart = bPart
      return bView
    case .c(let cPart):
      let cView = CView()
      cView.cPart = cPart
      return cView
    case .d(let dPart):
      let dView = DView()
      dView.dPart = dPart
      return dView
    }
  }
}

写完这个分类后,咱们就能够通过map函数来将枚举数组转化成为view数组了:

let views = ds.map { $0.view }

后面将其加入到UIStackView就能够了:

let stackView = UIStackView(arrangedSubviews: views)

至于如何配置stackView的距离,方向,这些咱们看看UIStackView的API就能够啦。

UIScrollView+UIStackView,ScrollView如何滑动

假如咱们之前有过通过SnapKitUIScrollView上增加子View的阅历,一般都会知道,要确保ScrollView能够正常滑动,一般情况下,咱们需求先要在ScrollView上面增加一个contentView,接着再将子View增加了到contentView上。

并且在最终一个子View进行布局的时分,对contentView的布局做一次布局更新,确保contentView的底部等于最终一个子View的底部。

咱们想如何确保ScrollView能够滑动?由ScrollView的contentSize属性决议。

好久之前看过@bestswifter大神的博客(该博客现在好像没有维护了),在ScrollView中增加contentView,并且在contentView增加子View,最终更新contentView的layout以到达更新ScrollView的contentSize的更新,从而确保能够滑动。

而这个细节在UIScrollView+UIStackView的布局结构上相同需求注意!!!

scrollView.addSubview(stackView)
stackView.snp.makeConstraints { make in
    make.edges.equalToSuperview()
}

stackView.axis = .vertical时,你会发现ScrollView在纵向根本就无法滚动,必须像之前UIScrollView上面增加子View的经验,增加一个contentView才行:

private func verticalLayout() {
    stackView.axis = .vertical
    stackView.spacing = 20
    stackView.alignment = .fill
    view.addSubview(scrollView)
    scrollView.snp.makeConstraints { make in
        make.edges.equalToSuperview()
    }
    let contentView = UIView()
    scrollView.addSubview(contentView)
    contentView.snp.makeConstraints { make in
        make.edges.equalToSuperview()
        make.width.equalTo(kScreenWidth)
    }
    contentView.addSubview(stackView)
    stackView.snp.makeConstraints { make in
        make.edges.equalToSuperview()
        make.bottom.equalTo(contentView.snp.bottom)
    }
    for _ in 0..<20 {
        stackView.addArrangedSubview(circle)
    }
}

不过一起你会发现,假如stackView.axis = .horizontal时,就算不增加contentView,ScrollView在横向仍是能够正常滑动:

private func horizontalLayout() {
    stackView.axis = .horizontal
    stackView.spacing = 20
    stackView.alignment = .center
    view.addSubview(scrollView)
    scrollView.snp.makeConstraints { make in
        make.edges.equalToSuperview()
    }
    scrollView.addSubview(stackView)
    stackView.snp.makeConstraints { make in
        make.edges.equalToSuperview()
    }
    for _ in 0..<20 {
        stackView.addArrangedSubview(circle)
    }
}

以上两点咱们在平时运用的时分都需求加以注意。

总结

本篇文章其实对上一篇文章里UI布局层面上的一点扩展,UIScrollView+UIStackView也能够说是一种不错的布局计划。

一起对于UIScrollView+UIStackView布局中的注意事项做了简单的解说。

不过我个人对于这种数据驱动型的页面构建,仍是更倾向于运用UITableView这种通过数据源构建页面。因为作为进行下拉刷新操作的时分,UITableView便是傻瓜操作,但是假如是UIStackView,相当于要对stackView进行UI上的重构,从用户感知体会和性能上都差一些。

参考文档

UIStackView inside UIScrollView

UIKit: Programmatically embed a UIStackView in an UIScrollView using AutoLayout

自己写的项目,欢迎咱们star⭐️

RxStudy:RxSwift/RxCocoa结构,MVVM模式编写wanandroid客户端。

GetXStudy:运用GetX,重构了Flutter wanandroid客户端。

本文正在参加「金石计划 . 分割6万现金大奖」