Swift中如何在同一个ViewController的两个UICollectionView复用同一份xib Cell?
实现方案
该需求完全可实现,同一个XIB cell支持注册给任意多个UICollectionView使用,无需修改XIB本身的代码,只需要调整ViewController里的注册逻辑和数据源方法即可,具体操作如下:
步骤1:给第二个collectionView注册同一份XIB
在viewDidLoad方法中,共用已经创建的nib实例,给第二个collectionView也完成注册即可,不需要重复创建nib对象。
步骤2:统一重用标识符
你原有代码中cellForItem方法里用的重用ID是yourItemView,和注册时的MainCollectionViewCell不一致,需要改成统一ID,否则会触发崩溃。
步骤3:区分不同collectionView的业务逻辑
两个collectionView的数据源、尺寸、交互逻辑大概率不同,需要在代理回调中判断当前触发回调的是哪个collectionView,返回对应的配置。
修改后的完整代码示例
import UIKit class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{ @IBOutlet var collectionView: UICollectionView! @IBOutlet var collectionViewTwo: UICollectionView! // 两个collectionView的数据源,可根据自己的业务替换成对应的数据模型 var firstList: [你的数据模型类] = [] var secondList: [你的数据模型类] = [] override func viewDidLoad() { super.viewDidLoad() let nib = UINib(nibName: "MainCollectionViewCell", bundle: nil) // 给第一个collectionView注册cell collectionView.register(nib, forCellWithReuseIdentifier: "MainCollectionViewCell") // 新增:给第二个collectionView注册同一份XIB cell collectionViewTwo.register(nib, forCellWithReuseIdentifier: "MainCollectionViewCell") // 如果你没有在Storyboard中绑定两个collectionView的delegate和dataSource,需要加下面两行 collectionView.delegate = self collectionView.dataSource = self collectionViewTwo.delegate = self collectionViewTwo.dataSource = self } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { // 判断当前是哪个collectionView,返回对应的数据条数 return collectionView == self.collectionView ? firstList.count : secondList.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // 统一使用注册时的重用ID,强转为自定义cell类 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MainCollectionViewCell", for: indexPath) as! MainCollectionViewCell // 根据collectionView的不同,给cell赋值不同的业务数据 if collectionView == self.collectionView { let currentData = firstList[indexPath.row] cell.lblTitle.text = currentData.标题字段 cell.imgProduct.image = UIImage(named: currentData.图片字段) // 剩余控件的赋值逻辑按你的业务补充 } else { let currentData = secondList[indexPath.row] cell.lblTitle.text = currentData.标题字段 cell.imgProduct.image = UIImage(named: currentData.图片字段) // 剩余控件的赋值逻辑按你的业务补充 } return cell } // 如果两个collectionView的cell尺寸不同,可以在该方法中做区分处理 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { if collectionView == self.collectionView { return CGSize(width: 120, height: 180) // 第一个collectionView的cell尺寸,按需求调整 } else { return CGSize(width: 200, height: 240) // 第二个collectionView的cell尺寸,按需求调整 } } // 如果两个collectionView的点击交互不同,可以在didSelectItemAt方法中同样按collectionView判断处理 }
- 后续如果需要调整cell的UI设计,只需要修改一次XIB和对应的
MainCollectionViewCell类,两个collectionView中的cell都会同步生效,不需要重复开发。
内容的提问来源于stack exchange,提问作者Swift
相关产品推荐
相关产品推荐

