UICollectionView 默认为一列,我如何获得两列?

Posted

技术标签:

【中文标题】UICollectionView 默认为一列,我如何获得两列?【英文标题】:UICollectionView defaulting to one column, how do I get two? 【发布时间】:2020-05-16 22:03:24 【问题描述】:

我最近一直在学习 UICollectionViews,我目前正在尝试实现一个。我需要显示两列,但无论我做什么,它都默认为一列。这里有很多类似的问题,建议使用collectionView 函数sizeForItemAt 调整 UICollectionView 单元格的宽度,但我似乎无法让它工作。

这是我的视图控制器代码:

class PreferencesViewController: UIViewController 

lazy var collectionView : UICollectionView = 
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = UICollectionView.ScrollDirection.vertical
    let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
    cv.translatesAutoresizingMaskIntoConstraints = false
    cv.register(CategorySelectorCell.self, forCellWithReuseIdentifier: "categorySelector")
    cv.backgroundColor = .clear
    return cv
()

override func viewDidLoad()
    super.viewDidLoad()
    view.backgroundColor = .white

    view.addSubview(collectionView)
    collectionView.backgroundColor = .blue
    collectionView.contentInsetAdjustmentBehavior = .always
    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true
    collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true
    collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: 40).isActive = true
    collectionView.heightAnchor.constraint(equalToConstant: view.frame.height/1.5).isActive = true


    self.view = view

我的代理扩展:

extension PreferencesViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    1

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "categorySelector", for: indexPath) as! CategorySelectorCell
    cell.cat = categories[indexPath.section]
    cell.backgroundColor = .red

    return cell

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    return CGSize(width: collectionView.frame.width/2.5, height: collectionView.frame.width/2)

func numberOfSections(in collectionView: UICollectionView) -> Int 
    10

任何指针表示赞赏!

【问题讨论】:

【参考方案1】:

同时添加这些UICollectionViewDelegateFlowLayout 方法

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat 
        return 0
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat 
        return 0
    

更新

也将插图设置为零

lazy var collectionView : UICollectionView = 
       let layout = UICollectionViewFlowLayout()
       layout.sectionInset = .zero
       layout.scrollDirection = UICollectionView.ScrollDirection.vertical
       let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
       cv.translatesAutoresizingMaskIntoConstraints = false
       cv.register(CategorySelectorCell.self, forCellWithReuseIdentifier: "categorySelector")
       cv.backgroundColor = .clear
       return cv
   ()

【讨论】:

不幸的是,这不起作用。它使单元格的宽度按预期变小了,但它们仍然在一列中。 感谢您的更新,但仍然无法正常工作。我也添加了你的功能。它可能与我的自定义单元类有关吗?如您所见,它只是一个imageView和一个标签。 不,它不是,虽然我找到了妥协。我相信这一定与我构建代码的方式有关。谢谢。【参考方案2】:

假设您的集合视图 UICollectionViewFlowLayout 有 16 个边缘插入开始和结束。和 minimumInteritemSpacingForSectionAt,minimumLineSpacingForSectionAt 到 16

然后你可以像这样计算你的单元格宽度

(view.frame.width-flowlayoutInsets-sectionSpacing)/2

这是代码

你的收藏视图

let coll: UICollectionView = 
        let layout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
        let coll = UICollectionView(frame: .zero, collectionViewLayout: layout)
        coll.backgroundColor = .systemPink
        //other stuff
        return coll
    ()

节和行间距

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat 
    return 16


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat 
    return 16

集合视图单元格大小

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        return CGSize(width: (view.frame.width-16-16-16)/2, height: 100)
        //1st 16 - left gap - flowlayout left inset
        //2nd 16 - middle gap - section spacing
        // 3rd 16 = right gap - flowlayout right inset
    

【讨论】:

这并没有解决我的问题,所以我认为这一定是我的问题。感谢您花时间回答我的问题。

以上是关于UICollectionView 默认为一列,我如何获得两列?的主要内容,如果未能解决你的问题,请参考以下文章

【Excel】多列数据合并为一列

是否可以在第一列不动的情况下使 UICollectionView 视图水平滚动?

熊猫:将多列汇总为一列,没有最后一列

将多行数据列转置为一列

将多列合并为一列

为一列熊猫数据框着色