简体   繁体   中英

Swift 3 - Add BarButtonItem To NavigationBar On Each ViewController Without Repeating Code

I have a BarButtonItem I want to add to every single ViewController in my app. How can I do this without having to copy/paste the button creation code and the action function into each ViewController? I would prefer reusability instead of having the same code in every ViewController.

Button Code:

    // Settings button
    let btn = UIButton(type: .custom)
    btn.setImage(UIImage(named: "icon-settings"), for: .normal)
    btn.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
    btn.addTarget(self, action: #selector(showSettings(sender:)), for: .touchUpInside)
    let settingsBtn = UIBarButtonItem(customView: btn)
    self.navigationItem.setRightBarButton(settingsBtn, animated: false)

The Action:

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "SettingsVC") as! SettingsViewController
    self.navigationController?.show(vc, sender: self)

I've tried adding this code to a separate Utility class, but you can't perform the segue from it since there is no way to access the button's parent ViewController from the action function if it is declared in the Utility class. I also tried subclassing UINavigationController and assigning that subclass to the NavigationController in my Storyboard, but it didn't work.

You can do this by adding a BaseViewController and inserting the code there. After that, on your rootviewController of your navigationController, you just extend from this BaseViewController . Doing that, and calling super in that function it will always having that code available and you don't need to repeat in every viewcontroller.

import UIKit

class BaseViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Settings button
        let btn = UIButton(type: .custom)
        btn.setImage(UIImage(named: "icon-settings"), for: .normal)
        btn.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
        btn.addTarget(self, action: #selector(showSettings(sender:)), for: .touchUpInside)
        let settingsBtn = UIBarButtonItem(customView: btn)
        self.navigationItem.setRightBarButton(settingsBtn, animated: false)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }

And then in your view controller you just extend BaseViewController

class ViewController: BaseViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        //Button should already appear here
    }

Note that ViewController should be your root view controller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM