如何在 Swift 中的 UIViewController 中添加多个集合视图?

我花了很多天才意识到: enter image description here

我想在我的 UIViewController 中添加两个不同的 CollectionView。 例如,我想把图像放在这些 CollectionView 中 每个 CollectionView 使用自己的图像。 这可能吗?

如果有人能帮我一把,我会很高兴的。 :)

72746 次浏览

是的,这完全有可能。你可以分配他们各自的 UICollectionViewDataSource 到不同的类或子类 CollectionView,将委托和数据源都分配到当前 viewController,并在委托方法中降低对 CollectionView 的引用,如下所示:

@IBOutlet collectionViewA: CustomCollectionViewA!
@IBOutlet collectionViewB: CustomCollectionViewB!




func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {


if let a = collectionView as? CustomCollectionViewA {
return a.dequeueReusableCellWithIdentifier("reuseIdentifierA", forIndexPath: indexPath)
} else {
return collectionView.dequeueReusableCellWithIdentifier("reuseIdentifierB", forIndexPath: indexPath)
}
}

子类 UICollectionView 如下:

class CustomCollectionViewA: UICollectionView {
// add more subclass code as needed
}


class CustomCollectionViewB: UICollectionView {
// add more subclass code as needed
}

这是可能的,您只需要将每个 UICollectionView 作为子视图添加,并将委托和数据源设置为 UIViewController。

举个简单的例子。假设您有一个正在工作的 UICollectionView,您应该能够根据自己的用法调整这段代码,以便相当容易地添加第二个:

let collectionViewA = UICollectionView()
let collectionViewB = UICollectionView()
let collectionViewAIdentifier = "CollectionViewACell"
let collectionViewBIdentifier = "CollectionViewBCell"


override func viewDidLoad() {
// Initialize the collection views, set the desired frames
collectionViewA.delegate = self
collectionViewB.delegate = self


collectionViewA.dataSource = self
collectionViewB.dataSource = self


self.view.addSubview(collectionViewA)
self.view.addSubview(collectionViewB)
}

在 cellForItemAtIndexPath 委托函数中:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
if collectionView == self.collectionViewA {
let cellA = collectionView.dequeueReusableCellWithReuseIdentifier(collectionViewAIdentifier) as UICollectionViewCell


// Set up cell
return cellA
}


else {
let cellB = collectionView.dequeueReusableCellWithReuseIdentifier(collectionViewBIdentifier) as UICollectionViewCell


// ...Set up cell


return cellB
}
}

在 numberOfItemsInSection 函数中:

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == self.collectionViewA {
return 0 // Replace with count of your data for collectionViewA
}


return 0 // Replace with count of your data for collectionViewB
}

您还可以以不同的方式命名集合视图出口(不需要子类化) :

@IBOutlet weak var collectionView: UICollectionView!


@IBOutlet weak var SecondCollectioView: UICollectionView!

方法:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCell", for: indexPath) as UICollectionViewCell


if(collectionView == self.SecondCollectioView) {
cell.backgroundColor = UIColor.black
} else {
cell.backgroundColor = self.randomColor()
}


return cell;
}

这是另一种方式。

您可以使用工厂设计模式来构建两个不同的集合视图,并通过函数返回它们。这是我为迅速4准备的工作版本。

这段代码放在一个单独的 helper 文件中:

import UIKit


class collectionViews {


static func collectionViewOne() -> UICollectionView {


let layout = UICollectionViewFlowLayout()
let collectionViewOne = UICollectionView(frame: CGRect(x: 0, y: 20, width: 200, height: 100), collectionViewLayout: layout)
return collectionViewOne


}


static func collectionViewTwo() -> UICollectionView {


let layout = UICollectionViewFlowLayout()
let collectionViewTwo = UICollectionView(frame: CGRect(x: 0, y: 300, width: 200, height: 100), collectionViewLayout: layout)
return collectionViewTwo


}




}

下面是视图控制器代码:

import UIKit


class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {




let collectionViewOne = collectionViews.collectionViewOne()
let collectionViewTwo = collectionViews.collectionViewTwo()


var myArray = ["1", "2"]
var myArray2 = ["3", "4"]


override func viewDidLoad() {
super.viewDidLoad()




collectionViewOne.delegate = self
collectionViewOne.dataSource = self
collectionViewOne.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
view.addSubview(collectionViewOne)




collectionViewTwo.delegate = self
collectionViewTwo.dataSource = self
collectionViewTwo.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell2")
view.addSubview(collectionViewTwo)


}


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


if collectionView == self.collectionViewOne {
return myArray.count
} else {
return myArray2.count
}


}


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


if collectionView == self.collectionViewOne {
let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath as IndexPath)


myCell.backgroundColor = UIColor.red


return myCell


} else {


let myCell2 = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell2", for: indexPath as IndexPath)


myCell2.backgroundColor = UIColor.blue


return myCell2
}


}




}

结果

以下是我对迅捷5和 Xcode 11的工作版本:

为相应的收藏视图创建渠道: 渠道:

@IBOutlet weak var bgCollectionView: UICollectionView!
@IBOutlet weak var frontCollectionView: UICollectionView!
var arrImages = [String : [UIImage]]()

ArrImages 包含如下内容

override func viewDidLoad() {
super.viewDidLoad()
arrImages = [
"frontImg": [//Front UIImage array],
"bgImg": [//Background UIImage array]
]
}


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let arrImg = arrImages["bgImg"] {
return arrImg.count
} else if let arrImg = arrImages["frontImg"]{
return arrImg.count
}
return 0
}

你可以用两种方法

  1. 使用 CollectionView 插座

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
if collectionView == self.bgCollectionView{
if let arrImg = arrImages["bgImg"]{
cell.imgView.image = arrImg[indexPath.row]
}
}else{
if let arrImg = arrImages["frontImg"]{
cell.imgView.image = arrImg[indexPath.row]
}
}
return cell
}
  1. 使用 CollectionView 标签: 这里背景图像 Collectionview 标记为1,前方图像 Collectionview 标记为2。

    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
    if collectionView == collectionView.viewWithTag(1){
    if let arrImg = arrImages["bgImg"]{
    cell.imgView.image = arrImg[indexPath.row]
    }
    }else{
    if let arrImg = arrImages["frontImg"]{
    cell.imgView.image = arrImg[indexPath.row]
    }
    }
    return cell
    }
    

Please Add Tag in CollectionView Like this: enter image description here

Thank You. Hope It's working for you !!

快速5答案!

如果尝试将两个 CollectionView 连接到同一个视图控制器,则 Xcode 将抛出一个错误“ Outlets can connect to repeat content”

解决方案:

前往故事板

  1. 通过插座连接第一个 CollectionView,在 viewDidLoad 中设置委托/数据源,然后通过标题到故事板中的属性检查器将标记添加到第二个 CollectionView,并将值从0更改为1

  2. 选择 second CollectionView 并转到连接检查器,选择 Committee 并将连接拖动到 UIViewController,对于 dataSource 也是如此。

  3. 只需检查哪个 CollectionView 正在通过。

     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
    
    if collectionView == collectionView.viewWithTag(1) {
    
    
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "secondCollectionView", for: indexPath)
    
    
    return cell
    }
    
    
    else {
    
    
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "firstCollectionView", for: indexPath) as! HomeMainCollectionViewCell
    
    
    cell.configureCell()
    
    
    return cell}
    }