iOS 的 paged controller 的一种思路

实现下图的效果

在这里插入图片描述

层次关系为:

  • Collection View 有一个 header,

header 上面有一个 scroll view

  • Collection View 还有很多 cell

图中可视区域内,有 6 个

效果是,点击 scroll view 上面的 item,

可以更新下面 cell 的内容

第一部分,自定义布局 Collection View layout

布局精华

class HanGridLayout: UICollectionViewLayout {
  override public func prepare() {
     guard let collectionView = collectionView else {
         return
     }
    
     prepareCache()
     contentHeight = 0
     // 配置 header 的位置,
     let headerH = layout.headSize.height
     let headerIP = IndexPath(item: 0, section: 0)
     let headerAttributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: CommonComponent.header.kind, with: headerIP)
      headerAttributes.frame = CGRect(x: 0, y: contentHeight, width: UI.std.width, height: headerH)
      var cellX: CGFloat = layout.contentEdge.left
        
      cache[.header]?[headerIP] = headerAttributes

      contentHeight += (headerH + layout.contentEdge.top)
            let count = collectionView.numberOfItems(inSection: 0)

        // 配置 cell 的位置
            for item in 0 ..< count {
                  let cellIndexPath = IndexPath(item: item, section: 0)
                  let attributes = UICollectionViewLayoutAttributes(forCellWith: cellIndexPath)
                
                attributes.frame = CGRect( x: cellX, y: contentHeight, width: layout.itemSize.width, height: layout.itemSize.height )
                  // 主要是,这里有一个换行
                contentHeight += layout.exceed(origin: &cellX, limit: collectionViewWidth)
                  cache[.cell]?[cellIndexPath] = attributes
            }
            // 这里有一个兼顾显示
            // 对于最后一行的格子,内容的呈现
            if count % 2 == 1{
                contentHeight += layout.itemSize.height
            }
 
      contentHeight += layout.contentEdge.bottom
  }
}

第 2 部分,header 上面的滚动条

主要是状态的管理,

旧状态抹去,

新状态呈现




class HanLanTopV: UICollectionReusableView {

    @IBOutlet weak var midView: UIView!
    // 文本转 UILabel
    var list = [String]()
    // 滚动视图
    lazy var scroll = UIScrollView()
    var names = [UILabel]()
    
    var bags = [Disposable]()
    
    //   动画的,底部的那条线
    lazy var line: UIView = // ...
    
    override func awakeFromNib(){
        super.awakeFromNib()
        //  初始化配置
        if scroll.superview == nil{
            midView.addSubs([scroll])
        }
        if line.superview == nil{
            scroll.addSubs([line])
        }
        scroll.snp.makeConstraints { (m) in
            m.edges.equalToSuperview()
        }
    }
    
    
    func config(package press: String, name n: String, config src: String?, list info: SubNameInfo, selected sIdx: Int){
        // 状态还原
        bags.forEach {
            $0.dispose()
        }
        names.forEach {
            $0.removeFromSuperview()
        }
        bags.removeAll()
        names.removeAll()
        // ...
        // 简单的显示配置
        
        // 每次刷新出来,
        // 底部的标签,都是动态生成
        let temps = info.names.map { (str) -> UILabel in
            let l = UILabel()
            l.text = str
            l.isUserInteractionEnabled = true
            l.textAlignment = .center
            l.textColor = UIColor(rgb: 0x404248)
            l.font = UIFont.regular(ofSize: 14)
            return l
        }
        names.append(contentsOf: temps)
        scroll.addSubs(names)
        
        for i in 0..

github repo

你可能感兴趣的:(ios)