Swift - 将self.navigationController调用到自定义单元类中

时间:2015-08-12 05:48:05

标签: ios swift uicollectionviewcell

夫特:

我有UICollectionViewController和另一个文件/类UICollectionViewCell

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

类似的东西:

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

我在didSelectItemAtIndexPath UICollectionViewController中实施推送没有问题,但我想从注册到UICollectionViewController的自定义单元格类中执行此操作。

当我尝试从自定义单元格类推送视图时,遗憾的是我无法访问self.navigationController

此外,我想100%以编程方式执行此操作。我没有使用Storyboard或Nib文件

提前致谢。

3 个答案:

答案 0 :(得分:7)

这是一个坏主意。观点不应该/做那种逻辑。你应该把它留给控制器(这是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)
}

尽管如此,我无法想到,这有什么意义。所以重新考虑你的架构。

通过在纸上绘图来可视化实体的通信。您必须绘制模型视图控制器,并且只允许控制器#34 ;谈话"到其他控制器

查看thisthis

答案 1 :(得分:3)

我最近也提出了这个问题,我有办法证明Akhilrajtr评论,因为它也可以帮助其他人。

首先在您的单元格类中,您需要在文件顶部使用协议:

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

然后在你的单元格类变量中添加:

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

答案 2 :(得分:0)

我想扩展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
}

至少在我的情况下,这对我有用。