I have three screen as below, now i go from the list of hotels to their detail view and from their to the ratings page, i perform the ratings and come back to detail page with ratings added, but now however , if i were to use the back button the navigation takes me back to ratings page instead of main page with hotels list , can any one please suggest how to avoid it ...
A->B->C but when coming back C->B but now B->C instead of B->A
SOLVED
So here is the mistake i was making
let backimage = UIImage(named: "back")
navigationController?.navigationBar.backIndicatorImage = backimage
navigationController?.navigationBar.backIndicatorTransitionMaskImage = backimage
navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: #selector(handleBackButton))
I was trying to hit the navigation bar back button item and make it do the work, it would reset back to default, what i need was to target navigationItem and not navigationcontroller, which i did and now from my handler it goes to root controller like below
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "", style: .done, target: self, action: #selector(handleBackButton))
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "back"), style: .plain, target: self, action: #selector(handleBackButton))
#objc func handleBackButton() {
_ = navigationController?.popToRootViewController(animated: false)
}
Following scenarios code u can use:
1) C->B or B->A
self.navigationController?.popViewController(animated: true)
2) C->A
self.navigationController?.popToRootViewController(animated: true)
If you are using navigationController, to pop back manually you have to use.
_=self.navigationController?.popViewController(animated: true)
For pop to a specific view controller you have to use
self.navigationController?.popToViewController(yourViewController, animated: true)
But before this you have to confirm that the navigation array contains the view controller to pop.
But this is not required for default navigation back button.
I think your issue is with pushing view controller to navigationController.
Please refer the codes for push:
self.navigationController?.pushViewController(yourViewController!, animated: true)
Note: pop will not work with presentViewController
Related
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.
I'm implementing a photo gallery via a UIPageViewController subclass (called GalleryController) embedded in a UINavigationController. The navigation bar hides when I tap, but the animation is odd:
https://www.youtube.com/watch?v=9SLF3Nq3uNE
Here's the code in GalleryController:
override var navigationItem: UINavigationItem {
let item = super.navigationItem
// Access super and add items to it.
// Don't create a new UINavigationItem instance — that breaks the back button.
let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
space.width = touchSize / 2
item.rightBarButtonItems = [
UIBarButtonItem(title: "All Photos", style: .plain, target: self, action: #selector(showAllPhotos)),
space,
UIBarButtonItem(title: "Delete", style: .plain, target: self, action: #selector(deletePhoto))
]
return item
}
This problem started occuring only after the page view controller was introduced.
What's causing this, and how do I fix it?
The solution turned out to be to do the following in the init of the UIPageViewController subclass:
automaticallyAdjustsScrollViewInsets = false
I don't know why it works, but it does.
I was earlier doing this in the child view controller (that represents a single page of the page view controller), but that wasn't working.
I'm having
a problem getting a button to show on a navigation controller. I have researched this and I think it has to do with how navigation works. Pushed and Popped from a stack.
Here is what I have:
I have the initial view as a navigation controller. This controller calls several views but the view that I'm having an issue with is a UICollectionViewController. This is called from a button click on the first viewController connected to the navigationController. I then have a segue setup that goes from the UICollectionViewCell to a new ViewController. So I'm assuming this is a second level NavigationController.
Secondly I have a Back Button Image that is displayed on my navigation instead of the text < Back.
The back button shows fine in the navigation controller on all the views except for the one called from the second level segue.
As I understand from reading other posts on this topic it is because a new navigation Controller is created on the second level segue.
I'm fine with that because everything works fine but I need the button to show on that second navcontroller.
I was trying to programmatically add the button to the navigation controller associated with the current view. I am using this code:
override func viewDidLoad() {
super.viewDidLoad()
var image = UIImage(named: "NavLogo")
var back_image = UIImage(named: "BackButton")
image = image?.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
back_image = back_image?.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
self.navigationController?.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.plain, target: nil, action: nil)
self.navigationController?.navigationItem.leftBarButtonItem = UIBarButtonItem(image: back_image, style: UIBarButtonItemStyle.plain, target: nil, action: nil)
}
This code does not seem to add the button to the current navigation controller.
This project is using Swift 3 and Xcode 8
Use
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.plain, target: nil, action: nil)
instead of
self.navigationController?.navigationItem.rightBarButtonItem = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.plain, target: nil, action: nil)
The reason for this is explained in this link.
I want to hide the text of the back button on the navigation bar and so have found past questions such as this: UINavigationBar Hide back Button Text
However I can't change the text at all, either via using the storyboard, or in code.
See screenshot below for attempt at changing it using the storyboard:
Or if I try to do it programatically by adding the following to viewDidLoad of the pushed view controller
self.navigationItem.backBarButtonItem?.title = "stuff"
It has no effect, nor does moving the same line of code to the view controller doing the pushing.
How come it won't change at all regardless of how I'm trying to change it?
How come using the storyboard, the navigation item title can be set, but not the back button text?
If I add the following to the pushed view controller then I can get the text to change:
UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Normal)
UIBarButtonItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Highlighted)
But I would like to understand why none of the other ways of trying to change it have any effect
The title of the back button gets automatically set to the title of the view controller that it will go back to.
To do what you want, you'll have to hide the back button and insert your own button with your own image.
Annoying == #YES.
As Brett mentioned above, a new bar button must be created to change the text.
To set the title of the back button, try the following code:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Stuff" style:UIBarButtonStylePlain target:nil action:nil];
Or make it in storyboard by adding a bar button item to your navigation bar.
When it comes to segue from tabBarController to a normal navigation controller, it is always easy to get confused in implementing backBarItem.
The trick is about which controller the backBarItem belongs to. If we navigate from controller A to controller B, then the backBarItem, which is the back button appearing on the controller B's navigation bar, actually belongs to controller A. So we just need to find the right controller to edit the backBarItem.
Solution 1. In the controller A, set the backBarButton self.tabBarController?.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .done, target: self, action: nil)
//M: In controller A
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .done, target: self, action: nil)
}
Solution 2. We can use a customised leftBarButton in controller B to cover controller A's backButton. navigationItem.leftBarButtonItem = UIBarButtonItem(title: "<", style: .done, target: self, action: #selector(tapBackButton)), then set the action of the leftBarButton to go back to the previous controller.
//M: in Controller B
override func viewDidLoad() {
super.viewDidLoad()
//M: Hide the default back button.
//M: backBarItem will be covered by the leftBarItem anyway, here is to add an extra handling.
navigationItem.hidesBackButton = true
//M: Customize a leftBarButton.
navigationItem.leftBarButtonItem = UIBarButtonItem(title: " < ", style: .done, target: self, action: #selector(tapBackButton))
//M: Customize the color and font size to the leftBarButton
navigationItem.leftBarButtonItem?.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 25)], for: .normal)
}
//M: Set the action of the leftBarButton to go back.
#objc func tapBackButton(_ sender:Any){
self.navigationController?.popToRootViewController(animated: true)
}
View hierarchy:
UINavigationController
->UITableViewController(1)
->UITableViewController(2)
->UIViewController(3)
In 1 and 2 I have this code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
self.navigationItem.backBarButtonItem?.title = ""
}
It should override the back button title of the next view controller pushed on the current view controller. It works from 1 -> 2. But it does not work for 2 -> 3. In 3 the back button title has a title, the name of the previous UITableViewController.
Any ideas whats wrong? I am using swift, xcode6.1 and iOS8.1
You could init a new back button with no title. Just put this in the viewDidLoad() of each view controller.
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
--
I am going to extend this answer with my experience. So I managed to remove the title of the back button to display just the back arrow. In storyboard you have to select the navigation item that displays the title inside the navigation bar of the previous view controller. There is a property called Back Button. Just enter a space and save. It will remove the back button title.
Update
UIBarButtonItemStyle.Bordered was deprecated in iOS 8.0. Use UIBarButtonItemStyle.Plain instead.
thanks,
if you want using customer back button image, you can use this
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: “backImage”)
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: “ backImage”)
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: “”, style: UIBarButtonItemStyle.Plain, target: nil, action: nil)