For my current project we’ve got a design requirement that all screens have a simple “Back” button instead of the default text that iOS provides when pushing a new controller.
I found that Swift’s inheritance model combined with extensions methods make this simple to implement in a re-usable fashion. To start this approach, I implemented a based controller which I called BaseController that manages the title of the backBarButtonItem. This is automatically handled by just inheriting from the BaseController. In the below example we create a new NotificationController using this pattern.
import UIKit class NotificationController: BaseViewController { override func viewDidLoad() { super.viewDidLoad() } }
The BaseController only has two lines of code. The first creates a string with the title of the back button. The second calls an extension method that manages the back button title information.
import UIKit class BaseViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let backTitle = NSLocalizedString("Back", comment: "Back button label") self.addBackbutton(backTitle) } }
The heavy lifting is performed in the UIViewController extension. Using the addBackbutton method to add a new UIBarButtonItem or update the current one’s title. If a new UIBarButtonItem is added the backButtonAction method is added to dismiss the controller on press.
import UIKit extension UIViewController { func backButtonAction() { self.dismissViewControllerAnimated(true, completion: nil) } func addBackbutton(title: String) { if let nav = self.navigationController, let item = nav.navigationBar.topItem { item.backBarButtonItem = UIBarButtonItem(title: title, style: UIBarButtonItemStyle.Plain, target: self, action: #selector(self.backButtonAction)) } else { if let nav = self.navigationController, let _ = nav.navigationBar.backItem { self.navigationController!.navigationBar.backItem!.title = title } } } }
The full code is available as a gist here.