j3141592653589793238
j3141592653589793238

Reputation: 1894

Why does a UIBarButtonItem action not trigger in a separate class?

I wrote a class that shall handle UIBarButtonItem taps. The initializer takes a reference to an UINavigationItem. All buttons etc. are attached to this UINavigationItem. I tried to connect them with actions (didPressMenuItem()), but when I click the button, the action is not triggered (nothing is written to the console nor the breakpoint I set is triggered).

How can I link the UIBarButtonItem to the function defined in this class?

internal final class NavigationBarHandler {

    // MARK: Properties
    private final var navigationItem: UINavigationItem?

    // MARK: Initializers
    required init(navigationItem: UINavigationItem?) {
        self.navigationItem = navigationItem
    }



    internal final func setupNavigationBar() {
        if let navigationItem = navigationItem {
            let menuImage = UIImage(named: "menu")?.withRenderingMode(.alwaysTemplate)
            let menuItem = UIBarButtonItem(image: menuImage, style: .plain, target: self, action: #selector(didPressMenuItem(sender:)))
            menuItem.tintColor = .white

            navigationItem.leftBarButtonItem = menuItem
        }
    }

    @objc func didPressMenuItem(sender: UIBarButtonItem) {
        print("pressed")
    }

}

This is what happens in the view controller to which navigationItem the buttons etc. are attached.

class ContactsController: UIViewController {

    // MARK: View Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .red
        self.title = "Kontakte"

        let navigationBarHandler = NavigationBarHandler(navigationItem: self.navigationItem)
        navigationBarHandler.setupNavigationBar()
    }
}

Upvotes: 1

Views: 167

Answers (1)

Zonily Jame
Zonily Jame

Reputation: 5359

Th problem here is that you're instantiating NavigationBarHandler inside viewDidload() which is why the memory reference dies after viewDidLoad() finishes. What you should do is to create the variable outside like this.

class ContactsController: UIViewController {

    var navigationBarHandler: NavigationBarHandler!

    // MARK: View Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .red
        self.title = "Kontakte"

        self.navigationBarHandler = NavigationBarHandler(navigationItem: self.navigationItem)
        navigationBarHandler.setupNavigationBar()
    }
}

This way the memory reference stays.

Upvotes: 2

Related Questions