如何根据用户选择在 CollectionView 标题下方显示不同的单元格?

Posted

技术标签:

【中文标题】如何根据用户选择在 CollectionView 标题下方显示不同的单元格?【英文标题】:How to display different cells below CollectionView header depending on users selection? 【发布时间】:2017-05-21 06:53:40 【问题描述】:

编辑:我正在尝试重新创建 instagram/twitter 个人资料页面。因此,如果我目前尝试的方式不起作用,请随时告诉我如何以完全不同的方式重新创建这些个人资料页面。

我已经设置了一个带有标题的 UICollectionView。在这个标题内,有一个 menuBar 有两个不同的选择选项。如果用户选择第一个索引,则 menuBar 返回 0。如果用户选择第二个索引,则 menuBar 返回 1。

        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CoverCell

            return cell
        

这里是菜单栏和它下面的collectionview单元格的图片:

我也有这个代码来设置单元格:

        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
            let menuBarIndex = profileMenuBarSelectionIndex.menuBarIndexSelection
            var cell: UICollectionViewCell
            switch menuBarIndex 
            case 0:
               cell = collectionView.dequeueReusableCell(withReuseIdentifier: test1CellId, for: indexPath) as! test1Cell
            case 1:
               cell = collectionView.dequeueReusableCell(withReuseIdentifier: test2CellId, for: indexPath) as! test2Cell
            default:
               cell = collectionView.dequeueReusableCell(withReuseIdentifier: test3CellId, for: indexPath) as! test3Cell
            
            return cell
        

编辑 2:我现在添加了此代码,其中 myTestActiontestAction 在不同文件中的委托函数。

var index: Int = 0
func testAction() 
    index = index == 1 ? 0 : 1
    collectionView.reloadData()


func myTestAction() 
    delegate?.testAction()


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    switch indexPath.row
    case 0:
        menuBarIndexSelection = 0
        menuBarIndexChangeFlag = 1
    case 1:
        menuBarIndexSelection = 1
        menuBarIndexChangeFlag = 2
    case 2:
        menuBarIndexSelection = 2
        menuBarIndexChangeFlag = 3
    default:
        menuBarIndexSelection = 0
    
    myTestAction()

我希望能够根据 menuBar 返回的值在标题下方显示不同的单元格。我该怎么做? 或者 如何重新创建 Instagram 个人资料页面?

【问题讨论】:

通过分享图片展示你的输出 好的,发一张它的样子 【参考方案1】:

检查 cellForRow 和supplimentaryViewsForHeader 的menuBar 值。当 menuBar 的值发生变化时,只需重新加载表格。在重新加载时,数据将根据您在 dataSources 中的检查显示。

// 菜单栏按钮点击

self.collectionView.reloadData()

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
     if menuBar == 0 
     // show this image
     else
     //show that image
     
        return cell
    

【讨论】:

这行不通,因为我已经使用as! CoverCell 铸造了可重复使用的单元格。我的封面单元格是一个具有许多属性的不同文件。【参考方案2】:

试试这个,

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 

//Take a variable menuBar. when the user tap change it's value to 0 or 1  and reload collection view when user tap on menu button.

    if menuBar == 0 
      return 0
    else
      return 1
    

【讨论】:

这不会做我想要的,只会改变显示的单元格数量。 @chillin' 将静态单元格添加到故事板中具有不同标识符的集合视图中,并根据您的条件返回单元格 我该怎么做?【参考方案3】:

出现您描述的编译器错误的原因是您创建了 4 个不同的变量,称为“cell”:

var cell: UICollectionViewCell
switch menuBarIndex 
case 0:
    var cell = ...
case 1:
    var cell = ...
default:
    var cell = ...

return cell

您在函数末尾返回的单元格实例从未被赋值。 在每种情况下分配第一个单元变量而不是创建新变量应该可以修复编译器错误:

var cell: UICollectionViewCell
switch menuBarIndex 
case 0:
    cell = collectionView.dequeueReusableCell(withReuseIdentifier: test1CellId, for: indexPath) as! test1Cell
case 1:
    cell = collectionView.dequeueReusableCell(withReuseIdentifier: test2CellId, for: indexPath) as! test2Cell
default:
    cell = collectionView.dequeueReusableCell(withReuseIdentifier: test3CellId, for: indexPath) as! test3Cell

return cell

-------------- 编辑 ---------

上面的答案修复了编译器错误,但不是实际问题。 我创建了一个小型示例项目,它可以满足需要并且可以正常工作。也许这有助于找出问题所在。我刚刚在 Xcode 中创建了一个单视图应用程序,这是项目中的一个视图控制器和单元格的代码:

class ViewController: UIViewController, UICollectionViewDataSource 

    var index: Int = 0
    var collectionView: UICollectionView?

    override func viewDidLoad() 
        super.viewDidLoad()

        let btn = UIButton(frame: CGRect(x: 10, y: 10, width: 200, height: 50))
        btn.backgroundColor = .green
        btn.setTitle("Change cell color", for: .normal)
        btn.setTitleColor(.black, for: .normal)
        btn.addTarget(self, action: #selector(testAction), for: .touchUpInside)
        view.addSubview(btn)

        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 10
        layout.minimumLineSpacing = 10
        layout.scrollDirection = .vertical
        collectionView = UICollectionView(frame: CGRect(x: 0, y: 60, width: view.frame.width, height: view.frame.height - 60), collectionViewLayout: layout)
        collectionView?.backgroundColor = .white
        collectionView?.dataSource = self
        collectionView?.register(RedCell.self, forCellWithReuseIdentifier: "red")
        collectionView?.register(BlueCell.self, forCellWithReuseIdentifier: "blue")
        view.addSubview(collectionView!)
    

    func testAction() 
        index = index == 1 ? 0 : 1
        collectionView?.reloadData()
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        var cell: UICollectionViewCell
        switch index 
        case 0:
            cell = collectionView.dequeueReusableCell(withReuseIdentifier: "red", for: indexPath)
        case 1:
            cell = collectionView.dequeueReusableCell(withReuseIdentifier: "blue", for: indexPath)
        default:
            cell = UICollectionViewCell()
        
        return cell
    

    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 7
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize 
        return CGSize(width: 50, height: 50)
    


class RedCell: UICollectionViewCell 

    override init(frame: CGRect) 
        super.init(frame: frame)

        backgroundColor = .red
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


class BlueCell: UICollectionViewCell 

    override init(frame: CGRect) 
        super.init(frame: frame)

        backgroundColor = .blue
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【讨论】:

好的,应用了这些更改。但是还是不行 什么不起作用?你不会再收到编译器错误了,对吧? 正确,编译器错误消失了。但它没有回答我的问题 好的。那么究竟是什么不起作用?切换菜单栏时是否显示了错误的单元格,还是总是相同的单元格,或者究竟是什么问题? 下面总是显示相同的单元格。当我在菜单栏中选择其他按钮时它不会改变

以上是关于如何根据用户选择在 CollectionView 标题下方显示不同的单元格?的主要内容,如果未能解决你的问题,请参考以下文章

如何更新在 Swift 4 之前和现在选择的 CollectionView 单元格?

根据是不是选择了 Xamarin CollectionView 项来确定 ReactiveUI 中的 CanExecute

如何根据内容设置collectionview单元格宽度?

如何在选择行方法collectionview中播放视频

如何根据标签大小调整 CollectionView 高度

如何在 CollectionView 中选择单元格图像然后转到 ViewController