Swift - 将 self.navigationController 调用到自定义单元格 class

Swift - Call self.navigationController into custom cell class

Swift:

我有 UICollectionViewController 和另一个 file/class UICollectionViewCell

目标是从我的自定义单元格 class 推送 UIViewController

像这样:

self.navigationController?.pushViewController(vc, animated: true)

我在 UICollectionViewController 中实现从 didSelectItemAtIndexPath 推送没有问题,但我想从注册到我的 UICollectionViewController.[=19 中的自定义单元格 class 执行此操作=]

当我尝试从自定义单元格推送视图时 class 不幸的是我没有访问权限 self.navigationController

我还想 100% 以编程方式执行此操作。我不使用 Storyboard 或 Nib 文件

提前致谢。

这是个坏主意。观点不应该是have/do那种逻辑。你应该把它留给控制器(这就是 MVC-Pattern 的意思)。

无论如何:

class MyCollectionViewCell: UITableViewCell {
    var myViewController: MyViewController!
}

当单元格出列时,您可以这样设置:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
    let cell: MyCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(myCellIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell
    let nvc: UINavigationController = UIStoryboard(name: "myStoryboard", bundle: nil).instantiateViewControllerWithIdentifier("myNavigationController") as! UINavigationController
    cell.myViewController = nvc.childViewControllers.first as! MyViewController

    return cell
}

以及选择:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
    let cell: MyCollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath) as! MyCollectionViewCell

    // I don't know where vc comes from
    cell.myViewController.navigationController?.pushViewController(vc, animated: true)
}

不过,我想不出任何有意义的案例。因此,再次重新考虑您的架构。

通过在纸上绘制来可视化实体之间的通信。您必须绘制 ModelsViewsControllers,并且仅绘制 Controllers 被允许 "talk" 给其他 控制器

看看this and this

我最近也想到了这个问题,我有办法演示 Akhilrajtr 评论,因为它也可能对其他人有所帮助。

首先在您的单元格中 class 您需要在文件顶部有一个协议:

protocol YourCellDelegate: NSObjectProtocol{
    func didPressCell(sender: Any)
}

然后在单元格 class 变量中添加:

var delegate:YourCellDelegate!

当您在单元格中执行某些操作时,触发协议的功能:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
    delegate.didPressCell(sender: indexPath)
}

在你的超级主控制器上,你应该符合你创建的委托:

class MyViewController: UIViewController, YourCellDelegate{...}

然后,实现协议的功能,按下单元格时触发,就像你之前定义的那样:

func didPressCell(sender: Any){
    let vc = SomeViewController()
    self.navigationController?.pushViewController(vc, animated: true)
}

当然不要忘记在 cellForItem 函数的单元格实例化部分为您的委托提供引用:

cell.delegate = self

我想扩展 ezcoding 答案。所以代替这个代码

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
    let cell: MyCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(myCellIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell
    let nvc: UINavigationController = UIStoryboard(name: "myStoryboard", bundle: nil).instantiateViewControllerWithIdentifier("myNavigationController") as! UINavigationController
    cell.myViewController = nvc.childViewControllers.first as! MyViewController

    return cell
}

您可以简单地使用self来获取视图控制器的当前实例,因此代码可以简化为

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
    let cell: MyCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(myCellIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell
    cell.myViewController = self

    return cell
}

这至少对我有用。