21

I am currently using SWRevealViewController for a sidebar menu in my app. When I click one of the options, the destination view controller doesn't have a 'back' button because it hasn't come from a proper view controller (i.e. page to go back to).

Therefore I am wanting to manually create a back button on the destination view controller which will go back to the home view controller.

I have looked at the code here: How do I manually set the "Back" destination in iOS apps

But I am struggling to implement this in Swift (one error after another!). Any help? Thanks!

EDIT

I have tried the suggestion below, but the back button just doesn't appear. This may have something to with the fact I have the navbar hidden in other views and do the following on the destination view:

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController.setNavigationBarHidden(false, animated:true)
    var myBackButton:UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    myBackButton.addTarget(self, action: "popToRoot:", forControlEvents: UIControlEvents.TouchUpInside)

    var myCustomBackButtonItem:UIBarButtonItem = UIBarButtonItem(customView: myBackButton)
    self.navigationItem.leftBarButtonItem = myCustomBackButtonItem
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func popToRoot(sender:UIBarButtonItem){
    self.navigationController.popToRootViewControllerAnimated(true)
}

Not sure why the back button won't show up?

Edit

This is the prepareForSegue from my sidebar view controller. If there is a way to check for the segue identifier 'test' then I can set the back button from here?

- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[_menuItems objectAtIndex:indexPath.row] capitalizedString];


if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
    SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;

    swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {

        UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
        [navController setViewControllers: @[dvc] animated: NO ];
        [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
    };

}

}
Community
  • 1
  • 1
Prateek
  • 1,724
  • 3
  • 15
  • 27

5 Answers5

25

You can write that in swift like this

Write this to add button on navigationController

    navigationController.setNavigationBarHidden(false, animated:true)
    var myBackButton:UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
    myBackButton.addTarget(self, action: "popToRoot:", forControlEvents: UIControlEvents.TouchUpInside)
    myBackButton.setTitle("YOUR TITLE", forState: UIControlState.Normal)
    myBackButton.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
    myBackButton.sizeToFit()
    var myCustomBackButtonItem:UIBarButtonItem = UIBarButtonItem(customView: myBackButton)
     self.navigationItem.leftBarButtonItem  = myCustomBackButtonItem

this will pops to rootViewController

    func popToRoot(sender:UIBarButtonItem){
       self.navigationController.popToRootViewControllerAnimated(true)
    }
codester
  • 36,891
  • 10
  • 74
  • 72
  • Thanks for the reply, I have added a little more to the above post – Prateek Jul 19 '14 at 20:28
  • because you have hide the navigation bar it will not show.Why you hiding `navigationBar` – codester Jul 19 '14 at 20:32
  • Because I don't need it in majority of my app through the way it functions, but I have allowed it to be shown on this view. When I apply the above code, the back button doesn't appear. The nav bar title is showing fine – Prateek Jul 19 '14 at 20:36
  • place the button anywhere set its frame accordingly.see my edited answer – codester Jul 19 '14 at 20:44
  • @user3797257 sorry forgot to set `frame` please verify now it is working.Really sorry for my mistake – codester Jul 19 '14 at 20:58
  • I haven't tested the frame bit as I want the nav bar's default back button to just work. Also, `leftBarButtonItem` doesn't work anymore and I had to use `backBarButtonItem` – Prateek Jul 19 '14 at 21:07
  • i have edited my answer please test it again it is working properly now.It was my mistake.Take updated code from my answer – codester Jul 19 '14 at 21:09
  • That works to show a button in this situation, but the button doesn't function on click. It doesn't direct to the root view controller (which is NOT the same as the original view controller that is linking to the destination view controller - if that makes sense?) – Prateek Jul 19 '14 at 21:13
  • I do not know the your navigationConroller stack.You can view it as self.navigationController.viewControllers by printing if your viewController is in stack than you can pop to that view controller – codester Jul 19 '14 at 21:18
  • 1
    This means I will lose the stock left arrow right? Is there any way to retain that? – Happiehappie Oct 13 '16 at 01:04
6

Swift 3.0 Solution:

    self.navigationController?.setNavigationBarHidden(false, animated:false)

        //Create back button of type custom

        let myBackButton:UIButton = UIButton.init(type: .custom)
        myBackButton.addTarget(self, action: #selector(ViewController.popToRoot(sender:)), for: .touchUpInside)
        myBackButton.setTitle("Back".localized(), for: .normal)
        myBackButton.setTitleColor(.blue, for: .normal)
        myBackButton.sizeToFit()

       //Add back button to navigationBar as left Button

        let myCustomBackButtonItem:UIBarButtonItem = UIBarButtonItem(customView: myBackButton)
        self.navigationItem.leftBarButtonItem  = myCustomBackButtonItem



 func popToRoot(sender:UIBarButtonItem){
        _ = self.navigationController?.popToRootViewController(animated: true)
    }
Sourabh Sharma
  • 8,222
  • 5
  • 68
  • 78
5

In Swift 2.1

I am customizing Navigation Bar Items this way

  • I can change Navigation bar background image, title text, text color
  • I can show/hide back button
  • I can Change Title/ Icon or custom action method

In AppDelegate I have

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
    {
        //Cutomize navigation bar
        let navBgImage:UIImage = UIImage(named: "dummy_navigation_bg_image")!
        UINavigationBar.appearance().setBackgroundImage(navBgImage, forBarMetrics: .Default)
        UINavigationBar.appearance().tintColor = UIColor.whiteColor()
        UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.whiteColor()];


        return true
    }

In ViewController I update Navigation Items in viewWillAppear method this way

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

    // MARK: - NavigationBar methods
    func setupNavigationBar ()
    {

        //current tab screen title
        tabBarController?.title = "Manage"

        //Hide back button or left bar button
        tabBarController?.navigationItem.leftBarButtonItem = UIBarButtonItem(title: " ", style: .Plain, target: nil, action: nil)

        //custom right bar button
        var image = UIImage(named: "dummy_settings_icon")
        image = image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
        tabBarController?.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.Plain, target: self, action:  "settingButtonAction")
    }

    func settingButtonAction()
    {
        print("Setting Button tapped")
        performSegueWithIdentifier("loadAccountSettingsSegue", sender: nil)

    }
swiftBoy
  • 35,607
  • 26
  • 136
  • 135
3

Here's an updated version for Swift 2/2.1:

self.navigationController? .setNavigationBarHidden(false, animated:true)
let backButton = UIButton(type: UIButtonType.Custom)
backButton.addTarget(self, action: "methodCall:", forControlEvents: UIControlEvents.TouchUpInside)
backButton.setTitle("TITLE", forState: UIControlState.Normal)
backButton.sizeToFit()
let backButtonItem = UIBarButtonItem(customView: backButton)
self.navigationItem.leftBarButtonItem = backButtonItem
jlhonora
  • 10,179
  • 10
  • 46
  • 70
1

Swfit 5 / XCode 11.4

override func viewDidLoad() {
    super.viewDidLoad()

    navigationController!.setNavigationBarHidden(false, animated: true)
    let myBackButton:UIButton = UIButton(type: UIButton.ButtonType.custom) as UIButton
    myBackButton.addTarget(self, action: #selector(popToRoot), for: UIControl.Event.touchUpInside)
    myBackButton.setTitle("YOUR TITLE", for: UIControl.State.normal)
    myBackButton.setTitleColor(UIColor.white, for: UIControl.State.normal)
    myBackButton.sizeToFit()
    let myCustomBackButtonItem:UIBarButtonItem = UIBarButtonItem(customView: myBackButton)
     self.navigationItem.leftBarButtonItem  = myCustomBackButtonItem
}

Also, popToRoot you should mark as @objc

 @objc func popToRoot() {
        //enter action here
    }
Roma Kavinskyi
  • 268
  • 4
  • 12