Swift:从 UICollectionViewCell 访问当前导航控制器

Posted

技术标签:

【中文标题】Swift:从 UICollectionViewCell 访问当前导航控制器【英文标题】:Swift: Accessing current navigation controller from a UICollectionViewCell 【发布时间】:2017-02-28 16:17:00 【问题描述】:

我有一个 UICollectionViewCell 类“ProductCell”;我正在尝试访问当前的导航控制器以更新 barbuttonicon。我已经尝试了以下代码,因为这是我在其他 UIViewControllers 中使用的:

    let nav = self.navigationController as! MFNavigationController
    nav.updateCartBadgeValue()

但它指出

ProductCell 类型的值没有导航控制器成员

我知道这不是UIViewController,但您肯定应该能够以同样的方式访问当前的导航控制器吗?

我也知道你可以通过以下方式使用UIApplication访问导航控制器:

let navigationController = application.windows[0].rootViewController as! UINavigationController

我不确定这是否是一个好方法。

非常感谢任何帮助

谢谢

【问题讨论】:

你几乎回答了你自己的问题。它不漂亮,但它一直有效。 想想集合视图和集合视图单元背后的设计原则。单元通常只是无生命的东西(数据模型某些部分的静态反射),不需要了解其他类型的状态或应用程序逻辑。在 MVC 模式中(我认为这很狡猾,但它工作得相当好)控制器——即集合视图控制器——应该处理它。 当您需要从视图访问控制器时,您做错了。修改从控制器(UICollectionView 的控制器)配置单元格的方法。 【参考方案1】:

UIResponder 链会在这里提供帮助。

您可以搜索响应者链以找到任何视图的控制器

extension UIView 

    func controller() -> UIViewController? 
        if let nextViewControllerResponder = next as? UIViewController 
            return nextViewControllerResponder
        
        else if let nextViewResponder = next as? UIView 
            return nextViewResponder.controller()
        
        else  
            return nil
        
    

    func navigationController() -> UINavigationController? 
        if let controller = controller() 
            return controller.navigationController
        
        else 
            return nil
        
    

controller() 将返回类型为UIViewController 的最近响应者 然后在返回的控制器上,您只需要找到它的导航控制器。你可以在这里使用navigationController()

【讨论】:

【参考方案2】:

最简单的方法是向单元类添加一个弱引用 UINavigationController 的属性

weak var navigationController: UINavigationController?

您需要在 cellForRow(atIndexPath:_) 方法中分配它。

let cell = tableView.dequeueReusableCell(withIdentifier: "yourReuseID") as! YourCellClass
cell.navigationController = navigationController //will assign your viewController's navigation controller to the cell

return cell

【讨论】:

【参考方案3】:

除非情况发生变化,否则这是一个很好的方法。给你一个更混乱的解决方案的例子......你可以添加一个

let hostViewController:UIViewController 

属性到你的单元格并添加一个初始化器来处理它

let cell = ProductCell(vc: self)

但我认为这不是更好的方法。你的建议很好。

let navigationController = application.windows[0].rootViewController as! UINavigationController

【讨论】:

以上是关于Swift:从 UICollectionViewCell 访问当前导航控制器的主要内容,如果未能解决你的问题,请参考以下文章

将子视图置于前面

水平方向自动移动 UICollectionCells

UIColletionViewCell 内的 UITextField 成为FirstResponder

从 Swift 3.0 转换为 Swift 2.3

Swift学习: 从Objective-C到Swift

从 swift 2.3 问题迁移到 swift 3.1