【问题标题】:UICollectionView: make first item's width different from the restUICollectionView:使第一个项目的宽度与其他项目不同
【发布时间】:2022-08-23 19:46:48
【问题描述】:

我目前正在尝试使用NSCollectionLayoutSection 实现以下布局。你有什么建议吗?使第一个项目宽 50 像素,同时保持其余项目 100 像素(可以是任意数量的项目)?解决方案必须是NSCollectionLayoutSection

我目前正在以相同的宽度显示它们,这不是所需的结果:

    let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0)))
    item.contentInsets = NSDirectionalEdgeInsets(top: 0,
                                                 leading: 0,
                                                 bottom: 0,
                                                 trailing: 8)
    
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .absolute(100),
                                             heightDimension: .absolute(100)), subitems: [item])
    
    let section = NSCollectionLayoutSection(group: group)
    section.contentInsets = NSDirectionalEdgeInsets(top: 16,
                                                   leading: 16,
                                                   bottom: 16,
                                                   trailing: 16)
    section.orthogonalScrollingBehavior = .continuous

我也尝试过使用绝对宽度,但这种方法运气不佳。

谢谢!

【问题讨论】:

    标签: swift uicollectionview uicollectionviewcompositionallayout nscollectionlayoutsection


    【解决方案1】:

    您可以通过创建两个单独的项目组来实现这一点(一个用于第一个具有半宽度的单元格,第二个用于其余单元格)。然后合并这两个组并将其添加到该部分。

    class ViewController: UIViewController {
    
        @IBOutlet var collectionView: UICollectionView!
        
        let headerId = "headerId"
        let categoryHeaderId = "categoryHeaderId"
        let colorarray = [UIColor.yellow, UIColor.green, UIColor.green, UIColor.green, UIColor.green, UIColor.green, UIColor.green, UIColor.green]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.navigationItem.title = "My Albums"
            collectionView.register(AlbumItemCell.self, forCellWithReuseIdentifier: AlbumItemCell.reuseIdentifer)
            collectionView.register(CategoryHeaderView.self, forSupplementaryViewOfKind: categoryHeaderId, withReuseIdentifier: headerId)
            collectionView.collectionViewLayout = createCompositionalLayout()
            collectionView.reloadData()
        }
    
        private func createCompositionalLayout() -> UICollectionViewCompositionalLayout {
            
            return UICollectionViewCompositionalLayout { (sectionNumber, env) -> NSCollectionLayoutSection? in
                self.firstLayoutSection()
            }
        }
        
        private func firstLayoutSection() -> NSCollectionLayoutSection {
            
            let cellWidth : CGFloat = 200
            let cellHeight : CGFloat = 200
            
            let smallItemSize = NSCollectionLayoutSize(widthDimension: .absolute(cellWidth/2), heightDimension: .absolute(cellHeight))
            let smallItem = NSCollectionLayoutItem(layoutSize: smallItemSize)
            let smallGroupSize = NSCollectionLayoutSize(widthDimension: .absolute(cellWidth/2), heightDimension: .absolute(cellHeight))
            let smallGroup = NSCollectionLayoutGroup.horizontal(layoutSize: smallGroupSize, subitem: smallItem, count: 1)
            smallGroup.contentInsets = .init(top: 0, leading: 8, bottom: 0, trailing: 8)
            
            
            let largeItemSize = NSCollectionLayoutSize(widthDimension: .absolute(cellWidth), heightDimension: .absolute(cellHeight))
            let largeItem = NSCollectionLayoutItem(layoutSize: largeItemSize)
            largeItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 8)
            let largeGroupSize = NSCollectionLayoutSize(widthDimension: .absolute(CGFloat((cellWidth + 8) * CGFloat((colorarray.count - 1)))), heightDimension: .absolute(cellHeight))
            let largeGroup = NSCollectionLayoutGroup.horizontal(layoutSize: largeGroupSize, subitem: largeItem, count: colorarray.count - 1 )
    
            
            let groupSize = NSCollectionLayoutSize(widthDimension: .absolute(cellWidth * CGFloat(colorarray.count)), heightDimension: .absolute(cellHeight))
            let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [smallGroup, largeGroup])
           
            let section = NSCollectionLayoutSection(group: group)
            section.orthogonalScrollingBehavior = .groupPaging
            
            return section
        }
        
    }
    
    extension ViewController: UICollectionViewDataSource {
        
        func numberOfSections(in collectionView: UICollectionView) -> Int {
            return 1
        }
        
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            colorarray.count
        }
        
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AlbumItemCell.reuseIdentifer, for: indexPath) as! AlbumItemCell
            cell.configure(color: colorarray[indexPath.row])
            return cell
        }
        
    }
    
    
    class AlbumItemCell: UICollectionViewCell {
        
      static let reuseIdentifer = "album-item-cell-reuse-identifier"
      let view = UIImageView()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            view.layer.cornerRadius = 10
            view.layer.masksToBounds = true
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        func configure(color: UIColor) {
            view.translatesAutoresizingMaskIntoConstraints = false
            contentView.addSubview(view)
            NSLayoutConstraint.activate([
                view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
                view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
                view.topAnchor.constraint(equalTo: contentView.topAnchor),
                view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            ])
            view.backgroundColor = color
    
        }
    }
    

    结果

    【讨论】:

    • 谢谢你。传递count 参数是关键。我完全错过了。
    猜你喜欢
    • 2023-01-01
    • 2020-08-15
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 2017-06-30
    相关资源
    最近更新 更多