【问题标题】:How to reuse a Collection View? -Swift如何重用集合视图? -迅速
【发布时间】:2018-01-30 01:46:07
【问题描述】:

在我尝试构建的应用程序中,我需要大量 UICollectionViews(大约 10 个)。我决定在不使用 Storyboards 的情况下制作 collectionViews(即完全在代码中)。 故事板使事情复杂化(对于许多 collectionViews)。

代码如下:

我)

   override func viewDidLoad() {

    super.viewDidLoad()
        //Create the collection View      

    let frame =                  CGRect(origin: CGPoint.zero , size: CGSize(width: self.view.frame.width , height: 50))
    let layout =                 UICollectionViewFlowLayout()
     collectionView1 =           UICollectionView(frame: frame, collectionViewLayout: layout)
    collectionView1.dataSource = self
    collectionView1.delegate =   self
    collectionView1.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellIdentifier")
    collectionView1.backgroundColor = UIColor.red
    view.addSubview(collectionView1) }

二)

 // TheData Source and Delegate 

extension ViewController : UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{


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

 return 5

}

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


        let cell =              collectionView.dequeueReusableCell(withReuseIdentifier: "cellIdentifier", for: indexPath)
        cell.backgroundColor = UIColor.darkGray
        return cell

}


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    return CGSize(width: 50, height: 50)
}
 }

这将在 View Controller 中创建一个 collectionView,但是如果我必须再创建十个这样,我将不得不重写上述代码 10 次。

所以我尝试创建一个单独的MyCollectionView 类,其中包含将collectionView 添加到ViewController 所需的基本实现,以便 我在视图控制器中所要做的就是像

这样简单
 override func viewDidLoad() {

super.viewDidLoad()

 let shoesCollection = MYCollectionView(frame : ...)
 self.view.addSubview(shoesCollection)   

 let foodCollection = MYCollectionView(frame : ...)
 self.view.addSubview(foodCollection)

 let carCollection = MYCollectionView(frame : ...)
 self.view.addSubview(carCollection)   

 }

或类似的东西。然而我没有成功。 我该怎么办?谢谢!

【问题讨论】:

  • 子类 ViewController 具有集合视图。
  • 我可以再详细一点,我不知道它是如何工作的。
  • 您应该继承 ViewController,而不是将 MYCollectionView 添加到每个视图控制器。假设使用相同集合视图的其他视图控制器之一,您应该像 MySecondViewController 类一样子类化:ViewController。那么你唯一需要改变的就是覆盖 UICollectionViewDataSource 和 UICollectionViewDelegate 来显示不同的内容。
  • 很抱歉我的问题有点不清楚。我需要将许多 collectionViews 添加到同一个视图控制器中。我希望能够分别配置每个视图控制器,以便它显示不同的内容。但是对于我添加的所有collectionViews,基本实现仍然是相同的。我更新了问题的最后一个代码块。
  • 知道了。现在这取决于您的集合视图在视图控制器中的显示方式。如果集合视图就像一行,那么您可能希望创建一个集合视图,其中包含您在其中创建的集合视图的集合视图单元格。

标签: ios swift uicollectionview reusability


【解决方案1】:

我只是给你一个简单的例子,虽然我不确定这是否是你想要的。同样,这完全取决于您正在实施的设计,但这可能是其中一个想法。

这个想法是

  1. 创建一个集合视图,它将填充您要添加的 10 个集合视图。

  2. 创建一个包含您要重复的集合视图的集合视图单元格。

  3. 向集合视图单元 (MYCollectionView) 提供不同的数据(食物、鞋子、汽车等)。

  4. 将每个数据馈送到单元格中的集合视图以填充各个数据。

视图控制器

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout  {
    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 10
        layout.scrollDirection = .vertical

        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(MYCollectionView.self, forCellWithReuseIdentifier: NSStringFromClass(MYCollectionView.self))
        collectionView.backgroundColor = .clear
        return collectionView
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(collectionView)
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        collectionView.frame = view.bounds
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

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


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.bounds.width, height: 100)
    }
}

MYViewController

class MYCollectionView: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal

        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.dataSource = self
        collectionView.delegate =   self
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellIdentifier")
        collectionView.backgroundColor = UIColor.red
        return collectionView
    }()

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

        contentView.addSubview(collectionView)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        collectionView.frame = bounds
    }

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

    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 15
    }

    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellIdentifier", for: indexPath)
        cell.backgroundColor = UIColor.darkGray
        return cell

    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: bounds.height, height: bounds.height)
    }

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

更新: 由于问题只是关于重用集合视图,我并没有真正将数据一直传递给重用的集合视图。假设当视图控制器加载时你有数据,比如说鞋子、食物和汽车的数组,而且每个数组组件也是数组。

例如,

let shoes = [...] //array of shoes
let foods = [...] //array of foods
let cars = [...] //array of cars
let data = [shoes, foods, cars]

现在您的数据数组有 3 个组件,这将决定您在问题中创建的集合视图的数量。所以在我的示例代码中的视图控制器中,

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return data.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: NSStringFromClass(MYCollectionView.self), for: indexPath) as! MYCollectionView
    let components = data[indexPath.item]
    cell.data = components
    return cell
}

在 MYCollectionView 中,您应该有一个变量 data。

var data:[WhateverYourDataModel] = [] {
    didSet {
        collectionView.releadData()
    }
}

public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return data.count
}

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellIdentifier", for: indexPath)
    cell.backgroundColor = UIColor.darkGray

    //let component = data[indexPath.item]
    //You should create a custom collection view cell to display whatever you want to display with the data, component. 

    return cell
}

为了使其干净,您的数据对象应该具有通用的基本模型,以便您可以将它们从视图控制器一直传递到 MYCollectionView 中的集合视图。

【讨论】:

  • 感谢您提供代码。我不清楚两件事。 A 在第 3 步之后,我将如何使用上面的代码来创建,比如 2 个 collectionViews,一个包含 3 个项目,另一个包含 4 个项目。 B 您在步骤 4 中说“将每个数据馈送到单元格中的集合视图”,您的意思是“馈送集合视图中的每个单元格 i>" ?.
  • @Tyrone 更新了我的答案以进行澄清。
  • 我现在终于明白了。再次感谢您的帮助。
  • @MicheleDall'Agata 我更新了代码。基本上我向水平集合视图添加了更多项目,因此您可以滚动并添加 collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath... 委托给水平集合视图。
  • @MicheleDall'Agata 我附上了图片。我复制了代码,一切正常。您可以复制新代码并在不添加代码的情况下尝试吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-04
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
  • 1970-01-01
相关资源
最近更新 更多