In UINavigationController, is there a way to button if the current viewcontroller is being dismissed as a result of the user pressing the back button or if the view controller is being dismissed programmatically with popViewControllerAnimated?
Note: I am specifically trying to differentiate between the 2 events. This is not a duplicate of this question as I am trying to figure out which event was called, not when the view controller is being dismissed
To Clarify:
I am trying to figure out whether the view is disappearing because
a) the back button was pressed or
b) popViewControllerAnimated was called
On viewWillDisappear method you can check values for isMovingFromParentViewController:
self.isMovingFromParentViewController()
which will return Bool, a Boolean value that indicates that the view controller is in the process of being removed from its parent.
Updated:
As replied, I think you will need to implement custom back button with its own method which can keep track of it.
self.navigationItem.leftBarButtonItem = nil;
self.navigationItem.hidesBackButton = true;
let backButton = UIBarButtonItem(title: "< Back", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
backButton.setTitleTextAttributes([NSFontAttributeName: UIFont(name: "Chalkduster", size: 20)!], forState: UIControlState.Normal)
navigationItem.backBarButtonItem = backButton
backButton.addTarget(self, action: "backButtonMethod",forControlEvents:UIControlEvents.TouchUpInside)
Related
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
I am creating a project where I need to have a default back button and custom filter button on the left side of the navigation bar.
I have created custom back button, custom filter button and add both of them to leftBarButtonItems
navigationItem.leftBarButtonItems = alignedLeftBarButtonItems()
func alignedLeftBarButtonItems() -> [UIBarButtonItem] {
let filterButton = createLeftCustomBarButton()
// back button creation
let backButton = UIBarButtonItem(image: R.image.navBackArrow(), style: .plain, target: self, action: #selector(self.backButtonPressed(_:)))
backButton.tintColor = UIColor.white
let barButtonsItems = [
backButton,
UIBarButtonItem(customView: filterButton)
]
return barButtonsItems
}
Things are fine and working.
Concern:
Default, User can go to the previous VC by sliding from left to
right. This functionality is lost in making this. Is there a way I can
have both buttons with the sliding functionality.
You need to use UIBarButtonItem to use default left or right swipe functionality for back button:
let backButton = UIBarButtonItem(image: Image.backButton, style: UIBarButtonItemStyle.plain, target: self, action: #selector(actionBackButton))
self.navigationItem.leftBarButtonItem = backButton
With Custom button, you cannot get this functionality
I am having tableview EKEvents, if a user taps on an event i will push EKEventViewController.
EKEventViewController comes default with delete button in toolbar how can I hide this.
I tried making a custom viewController subclass of EKEventViewController and in viewWillAppear i was hiding the navigationController's toolbar it was working but not properly.Another problem with this it will allows me to navigate to event details which is not required.
let eventViewControler = EKEventViewController()
eventViewController.event = self.events[indexPath.row]
eventViewController.allowsEditing = false
self.navigationController.pushViewController(eventViewControler)
How can I hide the only delete button.
You can customize rightBarButtonItem.
let rightButton : UIBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: self, action: "")
self.navigationItem.rightBarButtonItem = rightButton
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)
}