简体   繁体   中英

UIBarbuttonItem dismiss UIVIewcontroller

I added an extension to UIViewController to add a close button

    extension UIViewController {
      func addCloseButton() {
            let button = UIBarButtonItem(image: #imageLiteral(resourceName: "bar_close"), 
                                         landscapeImagePhone: nil,
                                         style: .done,
                                         target: self, 
                                         action: #selector(UIViewController.dismiss(animated:completion:)))
            navigationItem.leftBarButtonItem = button
      }
    } 

When i tap the barbutton i get a crash directly to AppDelegate. Any hints? Seems related to the selector.

You can't use dismiss(animated:completion:) as selector here because it takes two arguments bool and closure and bar button action pass args as UIBarButtonItem which cause app crash. so change your code like this.

extension UIViewController {
    func addCloseButton() {
        let button = UIBarButtonItem(image: #imageLiteral(resourceName: "rightgreen"),
                                 landscapeImagePhone: nil,
                                 style: .done,
                                 target: self,
                                 action: #selector(onClose))
        navigationItem.leftBarButtonItem = button
    }

    @objc func onClose(){
        self.dismiss(animated: true, completion: nil)
    }
}

However this question has accepted answer which load extra one method addCloseButton in each and every viewcontroller still posting a answer will going to help someone

NOTE : This example for adding barbutton item automatically and also handle action for pop view controller.

As Protocol extension doesn't provide a to implement selector methods so to get the rid of it I have created this solution.

First thing you need is BaseVC which is subclass of UIViewController and all of your view controller going to be inherited by BaseVC like your class LoginVC:BaseVC ...

now declare protocol

protocol PopableClass {
  func popSelf (animated:Bool)

}

extension PopableClass where Self : UIViewController {

    func popSelf (animated:Bool)  {
        self.navigationController?.popViewController(animated: animated)
    }

}

In your Base VC add two methods and call setupNavigationBar from viewDidLoad

func setupNavigationBar () {

    if self is PopableClass {
        let barbuttonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "back"), landscapeImagePhone: #imageLiteral(resourceName: "back"), style: .plain, target: self, action: #selector(popViewController))
        self.navigationItem.leftBarButtonItem = barbuttonItem
    }
}

//--------------------------------------------------------------------------------

@objc func popViewController () {
    if self is PopableClass {
        (self as! PopableClass).popSelf(animated: true)
    }
}

You did it !!

Now in whatever class you need back button to pop view controller just use like this

class PushedClass: BaseVC,PopableClass

Hope it is helpful

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