Swift - 从 UITableView 中嵌入的 UICollectionView 访问数据的问题
Posted
技术标签:
【中文标题】Swift - 从 UITableView 中嵌入的 UICollectionView 访问数据的问题【英文标题】:Swift - Issue accessing data from UICollectionView embedded in UITableView 【发布时间】:2020-04-09 01:21:36 【问题描述】:我有一个 tableView,它的原型单元格包含一个 UICollectionView。我已经根据本教程 (https://medium.com/@stasost/ios-how-to-build-a-table-view-with-multiple-cell-types-2df91a206429) 设置了 tableView,并且 UI 可以正常工作。我可以通过我的 tableView 将数据传递到 collectionView 中。
View Layout
When a collectionViewCell is selected it segues to another view.
我还没有弄清楚如何从 collectionViewCell 访问数据并将其传递给新视图。
collectionView 在 tableView 原型单元格中初始化。我已经尝试过 didSelectRow -> prepareForSegue(代码如下),但命令不会自动完成,并且无法正常工作。
这是 tableViewCell 的代码,其中设置了 collectionView。
编辑:为清楚起见删除了注释代码
import UIKit
class homeFeedTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource
@IBOutlet weak var feedCollectionView: UICollectionView!
var selectedEvent : Event?
var collectionItems = [CollectionViewModelItem]()
var collectionItem : CollectionViewModelItem?
@IBOutlet weak var sectionHeadingLabel: UILabel!
override func awakeFromNib()
super.awakeFromNib()
// Initialization code
feedCollectionView.delegate = self
feedCollectionView.dataSource = self
print("collection items \(collectionItems.count)")
for item in collectionItemsprint("type: \(item.type), title: \(item.eventTitle)")
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
// setup view model
var item: TableViewModelItem?
didSet
// if not right class, skip
guard let item = item as? TableViewModelFeed else
return
sectionHeadingLabel.text = item.sectionTitle
// create reuse identifier property
static var identifier: String
return String(describing: self)
import Foundation
import UIKit
extension homeFeedTableViewCell
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
// print("dataCount3: \(collectionItems.count) \(collectionItems[collectionItems.count-1].type)")
return collectionItems.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
// let cell = UICollectionViewCell()
// return cell
self.collectionItem = collectionItems[indexPath.row]
switch collectionItem!.type
case .yourEvents:
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier:YourEventsCollectionViewCell.identifier, for: indexPath) as? YourEventsCollectionViewCell
cell.item = collectionItem
print(cell.item?.type)
print(".yourEvents")
return cell
case .feed:
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: mainFeedCollectionViewCell.identifier, for: indexPath) as? mainFeedCollectionViewCell
cell.item = collectionItem
print(".feed")
return cell
return UICollectionViewCell()
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
print("\(collectionItems[indexPath.row].eventTitle) tapped")
func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "yourEventsToEventViewController" || segue.identifier == "feedToEventViewController"
print("prepare for segue1")
let destinationVC = segue.destination as! EventViewController
if collectionItem != nil
print("prepare for segue2")
destinationVC.backgroundImageUrl = collectionItem!.backgroundImageUrl
【问题讨论】:
【参考方案1】:UICollectionView 使用属性indexPathsForSelectedItems 跟踪其选定的 indexPaths。由于您在collectionView(didSelectItem: atIndexPath:)
中触发了segue,因此您选择的indexPath 在prepare(forSegue:)
期间可用。您可以尝试以下方法:
class MyViewController: UIViewController, UICollectionViewDelegate
...
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
performSegue(withIdentifier: "mySegue", sender: self)
...
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
super.prepare(for: segue, sender: sender)
guard let destinationVC = segue.destination as! EventViewController,
segue.identifier == "mySegue" else return
// In this context, your selected cell is the one who fired the segue
if let selectedIndexPaths = collectionView.indexPathsForSelectedItems,
let firstSelectedIndexPath = selectedIndexPaths.first
let selectedObject = collectionItems[firstSelectedIndexPath.row]
destinationVC?.backgroundUrl = selectedObject.backgroundUrl
顺序是:
-
您选择一个单元格(通过用户交互,即点击)。
didSelect
执行名为“mySegue”的转场(在本例中)。
在prepareForSegue
中,查找您选择的索引路径。假设你没有使用多选,你想要你的第一个也是唯一的 indexPath。使用该索引路径,您可以检索 collectionItems
数组中的数据。
【讨论】:
感谢您的建议!我能够按照建议使用 indesPath 清理选定的对象,但是 performSegue() 和 prepare(for segue) 函数不可用,因为我的 UICollectionViewDelegate 属于 UITableViewCell 类,而不是 UIViewController。我可以使用主视图控制器中的功能,但我不知道如何从 viewController 级别访问我的 TableViewCell -> collectionViewCell 中的信息。有什么建议吗? 知道了。还没有机会重温。今天晚些时候我会想出一个更好的回应。 一个快速的想法是让你的collectionViewCell 中的一个委托回到你的视图控制器。UIView
就是这样 - UI。它们并不意味着直接控制导航之类的东西,所以它们不能执行 segue 或类似的东西。这个责任属于UIViewController
,所以不知何故,你必须在那里处理电话。以上是关于Swift - 从 UITableView 中嵌入的 UICollectionView 访问数据的问题的主要内容,如果未能解决你的问题,请参考以下文章
Swift:使用 prepareForSegue 将 UIView 容器的高度设置为嵌入式 UITableView 的高度
如何从嵌入在 UITableViewCell (Swift) 中的 UICollectionView 的单元格中分离出来?