如何在 Swift 的 UIViewController 中添加多个集合视图?
Posted
技术标签:
【中文标题】如何在 Swift 的 UIViewController 中添加多个集合视图?【英文标题】:How can I add multiple collection views in a UIViewController in Swift? 【发布时间】:2015-04-29 06:45:59 【问题描述】:我尝试了很多天才意识到这一点:
我想在我的 UIViewController 中添加两个不同的 CollectionView。 例如我想把图像放在这些 collectionView 每个 CollectionView 使用自己的图像。 这可能吗?
如果有人能帮我一把,我会很高兴。 :)
【问题讨论】:
【参考方案1】:是的——这是完全可能的。您可以将它们各自的 UICollectionViewDelegates/UICollectionViewDataSources 分配给不同的类或将 CollectionViews 子类化,将委托和数据源都分配给您当前的 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
【讨论】:
“子类化 CollectionViews”是什么意思?我没能做到你所说的。【参考方案2】:这是可能的,您只需将每个 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
【讨论】:
我在这一行“let collectionViewA = UICollectionView()”上收到此错误“UICollectionView 必须使用非零布局参数初始化” 这对我不起作用!我收到此错误:*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“必须使用非零布局参数初始化 UICollectionView” 我认为“if collectionView == self.collectionViewA”这个比较太重了(你可能会在其他代码中继承这个习惯,这很糟糕)。我建议使用标签属性。这基本上是它的目的 我收到一条错误消息,指出“预期返回 'UICollectionViewCell' 的函数中缺少返回值”。我在 if 和 else 块中使用了两个 return 语句。 @Neck 更新了答案。这将起作用。只需在 if-else 块后添加“return UICollectionView()”【参考方案3】:您还可以以不同的方式命名集合视图出口(无需子类化):
@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】:您可以使用工厂设计模式构建两个不同的集合视图并通过函数返回它们。这是我的 swift 4 工作版本。
此代码位于单独的帮助文件中:
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
Result
【讨论】:
这个会滚动吗?你能用这个“func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)”吗? 是的,我在我正在开发的应用程序中使用了它,它滚动/选择很好 - 当您实现didSelectItemAt
时,只需确保使用 if/else 语句为每个应用程序设置正确的操作集合视图。
为什么只显示一项?【参考方案5】:
这是我的 swift 5 和 Xcode 11 的工作版本:
为对应的collectionviews创建 outlets: outlets:
@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
您可以通过两种方式做到这一点
-
使用 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
使用 CollectionView 标签: 这里 Background Images collectionview 标签是 1,Front Images 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
请在 CollectionView 中添加标签,如下所示:
谢谢。希望它对你有用!!
【讨论】:
以上是关于如何在 Swift 的 UIViewController 中添加多个集合视图?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UITabBarController 中加载所有视图?