首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多节UICollectionView

多节UICollectionView
EN

Stack Overflow用户
提问于 2021-02-03 10:15:31
回答 2查看 6.6K关注 0票数 0

大家好,我需要在一个水平滚动的collectionView中显示两个部分。

在第一部分,我需要10个单元,第二个部分需要9个单元。

我已经这样实现了,但是我不明白为什么当我选择第2节中的单元格时,indexPath.item的值是第1节的单元格的值。

编辑

正如您所看到的,我的collectionView有两个部分,设置如下的单元格。我不需要像这样显示单元格,但我需要节1位于上一行,它必须在同一行(0、1、2、3、4、5)和第2节中显示同一行的所有项目,并将项目显示为上一行。

我哪里做错了?

代码语言:javascript
复制
private func commonInit() -> Void {
        backgroundColor = .clear
        
        let cv = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
        cv.backgroundColor = .clear
        cv.delegate = self
        cv.dataSource = self
        cv.isPagingEnabled = true
        cv.showsHorizontalScrollIndicator = false
        addSubview(cv)
            
        if let layout = cv.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.scrollDirection = .horizontal }
        
        TimeSelectorCell.register(in: cv)
        
        cv.anchor(top: topAnchor, leading: leadingAnchor, bottom: bottomAnchor, trailing: trailingAnchor)

    }

    func numberOfSections(in collectionView: UICollectionView) -> Int { 2 }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if section == 0 { return 10 }
        else { return 9 }
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TimeSelectorCell.cellIdentifier, for: indexPath) as! TimeSelectorCell
    
        
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print(indexPath.item)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        .init(width: collectionView.frame.width / 4 , height: collectionView.frame.height / 2)
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 0 }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { 0 }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-03 18:35:53

在这种情况下,您必须使用的是iOS 13在CollectionView中的组合布局。这里有两个教程让你理解它-

  1. https://www.zealousweb.com/how-to-use-compositional-layout-in-collection-view/
  2. https://medium.com/better-programming/ios-13-compositional-layouts-in-collectionview-90a574b410b8
  3. WWDC视频- https://developer.apple.com/videos/play/wwdc2019/215/

对于您的情况,我在第二个教程中修改了示例

代码语言:javascript
复制
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return (section == 0) ? 10 : 9
}


func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 2
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print(indexPath)
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TimeSelectorCell.cellIdentifier, for: indexPath) as! TimeSelectorCell
    
    return cell
}

private func commonInit() {
    let cv = UICollectionView(frame: view.bounds, collectionViewLayout: createLayoutDiffSection())
    cv.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    TimeSelectorCell.register(in: cv)
    
    cv.dataSource = self
    cv.delegate = self
    
    addSubview(cv)
}

到目前为止,它几乎与您的代码相同。现在,createLayoutDiffSection()方法是-

代码语言:javascript
复制
func createLayoutDiffSection() -> UICollectionViewLayout {
    
    let layout = UICollectionViewCompositionalLayout { (sectionIndex: Int,
        layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
        
        let seperateFlow = true
        
        let columns = (sectionIndex == 0) ? 10 : 9
        
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .fractionalHeight(1.0))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 2, bottom: 0, trailing: 2)
        
        let groupHeight = NSCollectionLayoutDimension.fractionalWidth(0.2)

let widthFraction:CGFloat = (sectionIndex == 0) ? 1 : 0.9
        
        let groupSizeWidth:CGFloat = seperateFlow ? (widthFraction * 2) : 1
        
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(groupSizeWidth),
                                               heightDimension: groupHeight)
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: columns)
        
        let section = NSCollectionLayoutSection(group: group)
        if seperateFlow {
            section.orthogonalScrollingBehavior = .continuous
        }
        section.contentInsets = NSDirectionalEdgeInsets(top: 20, leading: 0, bottom: 20, trailing: 0)
        return section
    }
    return layout
}

如果两个部分的卷轴都不是分开的,那么设置-

让seperateFlow = false

这里需要理解的要点是-

大小类

我们可以根据需要使用四种大小选项,这将消除计算以实现预期输出的需要。让我们看看所有的size类:

  1. fractionalWidth():使用fractionalWidth,可以使用fractionalHeight设置单元格的宽度/高度与父单元的value
  2. estimate():成正比,可以用绝对值设置单元格的宽度/高度与父单元的height
  3. absolute():成正比,可以使用估计值将单元格的宽度/高度设置为固定的value
  4. estimate():,可以根据内容大小来设置单元格的宽度/高度。系统将决定内容的最佳宽度/高度。

核心概念

要构建任何组合布局,需要实现以下四个类:

  1. NSCollectionLayoutSize -宽度和高度维度是NSCollectionLayoutDimension类型,可以通过设置布局的小数宽度/高度(相对于其容器的百分比),或者通过设置绝对或估计的sizes.
  2. NSCollectionLayoutItem来定义--这是布局的单元格,它基于size.
  3. NSCollectionLayoutGroup在屏幕上呈现--它在水平、垂直或自定义forms.
  4. NSCollectionLayoutSection中保存NSCollectionLayoutItem --这用于通过传递NSCollectionLayoutGroup来初始化区段。各节最终组成了组成布局。
票数 3
EN

Stack Overflow用户

发布于 2021-02-03 18:28:34

代码语言:javascript
复制
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
     
    if (indexPath.section == 0 )
    {
      // cell of section 1
       print(indexPath.item)
    }else{
     // cell of section 2
      print(indexPath.item)
     }
     
   
}

你可以试试!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66025426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档