点击tableview内的collectionview单元格导航

Posted

技术标签:

【中文标题】点击tableview内的collectionview单元格导航【英文标题】:navigate on click of collectionview cell inside tableview 【发布时间】:2017-07-11 09:04:58 【问题描述】:

我有一个 tableview 单元格,我在其中添加了 collectionview 单元格(用于水平滚动)。

现在我想在按下水平集合视图的任何单元格时推送到其他导航控制器。怎么做 ?或者我如何定义单元格按下的委托方法。

代码:

ViewController.swift :

class ViewController: UIViewController 
    var categories = ["Action", "Drama", "Science Fiction", "Kids", "Horror"]


extension ViewController : UITableViewDelegate  

extension ViewController : UITableViewDataSource 

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? 
        return categories[section]
    

    func numberOfSections(in tableView: UITableView) -> Int 
        return categories.count
    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return 1
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! CategoryRow
        return cell
    


CategoryRow.swift

class CategoryRow : UITableViewCell 
    @IBOutlet weak var collectionView: UICollectionView!


extension CategoryRow : UICollectionViewDataSource 

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "videoCell", for: indexPath) as! VideoCell
        return cell
    



extension CategoryRow : UICollectionViewDelegateFlowLayout 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        let itemsPerRow:CGFloat = 4
        let hardCodedPadding:CGFloat = 5
        let itemWidth = (collectionView.bounds.width / itemsPerRow) - hardCodedPadding
        let itemHeight = collectionView.bounds.height - (2 * hardCodedPadding)
        return CGSize(width: itemWidth, height: itemHeight)
    


VideoCell.swift

class VideoCell : UICollectionViewCell 

    @IBOutlet weak var imageView: UIImageView!

【问题讨论】:

【参考方案1】:

在这里,您将在 CategoryRow 类上的委托方法 didSelectItemAtIndexPath 上单击单元格,然后您可以从那里触发委托以在 ViewController 内调用 ViewController.swift

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! CategoryRow
            cell.delegate = self
            return cell
        

VideoCell.swift

    protocol CategoryRowDelegate:class 
    func cellTapped()
    

CategoryRow.swift

    class CategoryRow : UITableViewCell 
         weak var delegate:CategoryRowDelegate?
        @IBOutlet weak var collectionView: UICollectionView!
    

     func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    if delegate!= nil 
    delegate?.cellTapped()
    
    

ViewController内添加委托函数

func cellTapped()
//code for navigation

【讨论】:

听起来不错:)【参考方案2】:

首先从 CategoryRow.swift 创建委托协议,如下代码

protocol CollectionViewSelectionDelegate: class 
    func didSelectedCollectionViewItem(selectedObject: AnyObject)

现在在 VideoCell.swift 上创建委托对象,如下所示

weak var delegate:CollectionViewSelectionDelegate? 

在返回单元格之前更改 ViewController.swift 代码

cell?.delegate = self

在 ViewController.swift 中重写 delegate 的方法,并从 UICollectionView Delegate 方法调用 VideoCell.swift 中的类似方法。

【讨论】:

【参考方案3】:

我认为在这种情况下使用通知会更好。

在集合视图的didSelectItem 中发布通知

NSNotificationCenter.defaultCenter().postNotificationName(notificationIdentifier, object: nil)

并在viewControllerviewDidLoad中添加一个观察者如下

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(pushToNew(_:)), name: notificationIdentifier, object: nil)

在新的pushToNew 函数中,执行你的转场

func pushToNew(notification: Notification) 
    // perform your segue here. Navigate to next view controller

【讨论】:

另一种解决方案。 如果可能的话,告诉我哪个更有效?使用通知或委托? 我们不能说哪个更有效。两者都在您的情况下执行功能。与委托相比,它更易于使用通知。检查这个答案。它有更多关于通知和代表的详细信息***.com/a/5325496/7456236【参考方案4】:

制定协议

protocol collectionViewCellClicked
    func cellClicked()

在主视图控制器中实现这个协议你的视图控制器看起来像这样

class ViewController: UITableViewController, collectionViewCellClicked func cellClicked() // Your Code  

您的 cellForRowAt 代表如下所示

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell indexPath: IndexPath) -> UITableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: <#T##String#>, for: <#T##IndexPath#>) cell.delegate = self return cell

在您的表格视图单元格中创建一个 collectionViewCellClicked 类型的变量 var delegate: collectionViewCellClicked?

在您的 didSelectItemAt 委托中

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) delegate.cellClicked()

【讨论】:

以上是关于点击tableview内的collectionview单元格导航的主要内容,如果未能解决你的问题,请参考以下文章

UITableViewCell 无法添加子视图

CollectionViews和TableView不在StackView中显示 - Swift 4

滚动视图内的pageviewcontroller内的iOS tableview

防止 tableview 单元格回收标签值

从 API 填充 TableView 内的 CollectionView

在 TableView 内的 CollectionView 中填充动态数据