Haider Ashfaq
Haider Ashfaq

Reputation: 53

Swift: Accessing current navigation controller from a UICollectionViewCell

I have a UICollectionViewCell class "ProductCell"; I am trying to access the current navigation controller in order to update a barbuttonicon. I have tried the following code as this is what I use in my other UIViewControllers:

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

However it states that the

value of type ProductCell has no member navigationController

I am aware that this is not a UIViewController but surely you should be able to access the current navigation controller the same way?

I also know that you can access the navigation controller by using UIApplication in the following way:

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

I am not sure if that is a good way of doing it though.

Any help is much appreciated

Thanks

Upvotes: 4

Views: 7759

Answers (3)

BangOperator
BangOperator

Reputation: 4437

UIResponder chain will help here.

You can search the responder chain to find the controller for any view

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() will return the closest responder that is of type UIViewController Then on the returned controller you just need to find its navigation controller. You can use navigationController() here.

Upvotes: 5

Mac Bellingrath
Mac Bellingrath

Reputation: 595

The simplest way is to add a property to you cell class that weakly references a UINavigationController

weak var navigationController: UINavigationController?

you will need to assign it in your cellForRow(atIndexPath:_) method.

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

return cell

Upvotes: 2

Mozahler
Mozahler

Reputation: 5303

Unless things change, this is a good way to do it. To give you an example of a messier solution... You could add a

let hostViewController:UIViewController 

property to your cell and add an initializer to handle it

let cell = ProductCell(vc: self)

But I don't think that's a better way to do it. your suggestion works fine.

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

Upvotes: 0

Related Questions