Add another back button to a Navigation Controller - ios

I have a navigation controller so when I click on a button on my main view, it opens another view with the "Back" navigation item.
What I'm trying to do is to add another item on my second view on the right, so this view should have a "Back" item, already working, and a new "Edit" item which does the same thing as Back button but I can get the prepareForSegue function to run some code in complement.
How can I achieve to do that ?
Here is what I tried :
I'm using two navigation controllers because I couldn't add an "Edit" item if my second view wasn't embed in a navigation controller.
So this is working, I have my two "Back" and "Edit" items, but I don't know how to manage to get the same behavior as the "Back" item on my "Edit" item, I tried segues but it doesn't work as expected.
Note that the button I talked about on my first view isn't shown in the editor nor its segue, I did it programmatically.

You can simple call popViewController(animated:) when the edit button is tapped.
class ViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
let editItem = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editButtonTapped(_:)))
self.navigationItem.rightBarButtonItem = editItem
}
#objc func editButtonTapped(_ sender: UIBarButtonItem)
{
self.navigationController?.popViewController(animated: true)
}
}
Storyboard:

Related

In navigation controler how to implement a add button opens a new view controller

I am new to swift , I have a very simple question. I implement a navigation controller with two items at top like this
I did this by adding a navigation controller to the project and then adding this lines of code in to the viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.title = ""
self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.navigationItem.setLeftBarButton(UIBarButtonItem(barButtonSystemItem: .add, target: self, action: Selector(("barButtonItemClicked:"))), animated: true)
}
now my question is about how to open a new view controller I mean a new page after clicks on plus (+) button at the navigation bar. I searched a lot but did not find any exact thing relate to this. Appreciate you if possible help me. thank you
Your code should be like this one:
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, style: .plain, target: self, action: #selector(performToVC))
#objc func performToVC() {
performSegue(withIdentifier: "vc", sender: self)
}
Here is code for Push TO OTherView Controller
#objc func PoushTOHistoryVC() {
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "HistoryViewController") as! HistoryViewController
self.navigationController?.pushViewController(secondViewController, animated: true)
}
here is Button for Add
self.navigationItem.setLeftBarButton(UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(PoushTOHistoryVC)), animated: true)
you need to add HistoryViewControlle to Stroyboard ViewController HistoryViewControlle and Don't forget
First you have to create new view controller which you have to open on that plus (+) button at the navigation bar. After creating new view controller you have to press and hold the control key on the keyboard and the click on the (+) button at the navigation bar and drag it to the new view controller and then release the click button image for reference, then it will show you a pop up with options such as show, show details etcimage for reference, select show option.

Unable to add barbuttonitem to navigation controller

I would like to integrate both navigation controller and tab bar controller in my project.But I am unable to add right barbutton to the navigation controller.
I have attached the screenshot of the storyboard
What I have done is I have added navigation controller to login screen and this time I am able to add barbuttonitem both by adding code as well as by dragging barbuttonitem to navigation controller.
let addBtn = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addTapped))
self.navigationItem.rightBarButtonItem = addBtn
Problem I am facing is after adding Tab bar controller I am unable to add rightbarbutton both by code as well as by dragging to the navigation controller. please help me.
When a ViewController is embedded in a NavigationController you use
self.navigationItem.rightBarButtonItem = addBtn
In your project Detail Screen isn't embedded in NavigationController directly. Detail Screen is embedded in TabBarController, TabBarController is embedded in NavigationController. So you should use
self.tabBarController?.navigationItem.rightBarButtonItem = addBtn
But this addBtn will be visible in all view controllers which are embedded in the TabBarController.
If you want to add the rightBarButton for only one viewcontroller, then embed the Detail Screen in a new NavigationController. Then you can add rightBarButton using
self.navigationItem.rightBarButtonItem = addBtn
You should be sure parent returns the top child controller of UINavigationController. In my case
parent?.parent?.navigationItem.right...
did the trick.
If you reuse the controller -as embedded or not- which you want add items to navigationItem, following example will work. However some logical changes may be needed.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard parent is UINavigationController else {
parent?.parent?.navigationItem.rightBarButtonItem = UIBarButtonItem()
return
}
navigationItem.rightBarButtonItem = UIBarButtonItem()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
guard parent is UINavigationController else {
parent?.parent?.navigationItem.rightBarButtonItem = nil
return
}
navigationItem.rightBarButtonItem = nil
}

Swift how to preserve navigation bar button items after push

In my root view controller I set an array of bar button items with images and assign them to the right bar button.
When I push the next view controller my navigation bar resets and only displays a back button.
Any way to preserve the navigation bar as it was set on the root view controller so it will display on all pages?
As user1046037 has said you can set the item buttons while you are preparing the segue.
Example:
let helpViewController = HelpViewController(nibName: "HelpViewController", bundle: nil)
let someLeftButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.refresh, target: self, action: "someAction")
helpViewController.navigationItem.leftBarButtonItem = someLeftButton
helpViewController.navigationItem.leftItemsSupplementBackButton = true
navigationController?.pushViewController(helpViewController, animated: true)
This one is to preserve the left button item and the back one.
helpViewController.navigationItem.leftItemsSupplementBackButton = true
If you are going to use the same button in several Viewcontrollers you can create a BaseViewController setting up the button and his behaviors.
class AHBaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
configureNavigationBar()
// Configure Common status bar if you want too.
}
func configureNavigationBar() {
let someLeftButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.refresh, target: self, action: "someAction")
navigationItem.leftBarButtonItem = someLeftButton
navigationItem.leftItemsSupplementBackButton = true
}
}
Then just inherit it, in the viewControllers that you want to show the button(s).
class HelpViewController: AHBaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
When you segue between view controllers using Push, you're going to get the default "horizontal slide" navigation animation which. Try "present Modally" or "present as popover".

Combine Seques with UINavigationController

I am building a mobile app which displays stats from multiple APIs.
The app shows different values based on the API that is active. At runtime, the user can select which API to display values for. However, the values are always displayed within the same Target view controller.
UINavigationController is in use and I'd like to defer to that for navigation and navigation UI, if possible, even though UITableViewControllers support navigation bars.
Please see the storyboard design image at the end of the question.
Environment: iOS 9/Swift 2.2/XCode 7
At runtime, the user will select a Choice view controller from the Select controller. What is the appropriate way to segue from one of the Choice view controllers, via a "Done" UIBarButton, to the Target controller? The Target controller does not change.
Must I programmatically define the right bar button to "Done" for every controller that is embedded within the UINavigationController?
class UIViewController: UITableViewController {
override func viewWillAppear( animated: Bool) {
super.viewWillAppear( animated)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
}
}
The proper way to return to the root view controller is:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.plain, target: self, action: #selector(MyViewController.done))
}
func done() {
if let navigationController = self.navigationController {
navigationController.popToRootViewController(animated: true)
}
}
}
You do need to programmatically add a "done" button; but it's more simple than that. Just select your root view controller, and copy/past the class in storyboard. Use your segues to push the correct view onto the UINavigation stack.

Cancel button instead of a back button in Navigation Controller

I have a general question concerning the navigation between views.
I have a view controller 1 embeded in a navigation controller. In the nav bar, I have a button to do add data, when pushed, it goes to view controller 2 through segue Show (in Storyboard). In view controller 2, I return to view controller 1 after collecting data when I click the button save in nav bar on the right. I collect data with:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {...}
I would prefer instead of a back button to have a cancel button in the view controller 2 to return to view controller 1.
I feel something is wrong in my design but I dont know what.
In fact I am looking for something very similar to app clock.
Do you have any idea?
Edit: Here is the story board. you will notice the loop beween the two controller. how to do when I click save to not have a back button automatically on the first controller?
You just have to select your UIBarButtonItem, click at show Attributes Inspector, click at Identifier and select "Cancel" from the drop-down menu.
#IBAction func cancelDownload(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
You can customize the text of the back button by adding this code to the view controller that contains it (in viewDidLoad):
let backItem = UIBarButtonItem(title: "Cancel", style: .Bordered, target: nil, action: nil)
navigationItem.backBarButtonItem = backItem

Resources