Hide back button in tabbar navigation controller - ios

I need to hide the Back that is overlapping with Cart
Edit 1
I have already added these things
override func viewWillAppear(animated: Bool) {
super.viewDidAppear(animated)
self.tabBarController!.navigationItem.title = "Orders"
// self.navigationItem.rightBarButtonItem = UIBarButtonItem(title:"Cart", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
self.tabBarController!.navigationItem.rightBarButtonItem = UIBarButtonItem(title:"Cart", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
self.tabBarController!.navigationItem.leftBarButtonItem = UIBarButtonItem(title:"Cart", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
self.navigationItem.hidesBackButton = true
}
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController!.navigationItem.title = "Orders"
self.navigationItem.title = "Order History"
// self.navigationItem.rightBarButtonItem = UIBarButtonItem(title:"Cart", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
self.tabBarController!.navigationItem.rightBarButtonItem = UIBarButtonItem(title:"Cart", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
self.tabBarController!.navigationItem.leftBarButtonItem = UIBarButtonItem(title:"Cart", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
// Do any additional setup after loading the view.
self.navigationItem.hidesBackButton = true
}

in this place
self.navigationItem.hidesBackButton = true
try this
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: UIView())
option-2
self.tabbarcontroller.navigationcontroller.navigationitem.hidesBackButton = true
self.tabBarController!.navigationItem.rightBarButtonItem = UIBarButtonItem(title:"Cart", style: UIBarButtonItemStyle.Plain, target: self, action: nil)
self.tabBarController!.navigationItem.leftBarButtonItem = UIBarButtonItem(title:"Cart", style: UIBarButtonItemStyle.Plain, target: self, action: nil)

self.navigationItem.hidesBackButton = YES;

Try with below code, write this code on view controller which appear after 1st navigationcontroller ( PushViewController ).
self.navigationItem.setHidesBackButton(true, animated: false)

self.tabBarController!.navigationItem.hidesBackButton = true

Related

Change Navigation Bar Item Dynamically - Swift

I am creating a NavigationBar with UIBarButtonItem which located on right side of screen. As default I set that setRightBarButton with UIBarButtonItem(image: UIImage(named: "edit"), style: .plain, target: self, action: #selector(editProfile)) and when I clicked on that it should change that rightBarButton to other title but it doesn't work.
Here is I tried to change with I clicked on it
#objc
func editProfile() {
self.navigationItem.setRightBarButton(cancelActionBar, animated: true)
}
This is object of cancelActionBar
let cancelActionBar = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelEdit))
And this is its action which change it back to default.
#objc
func cancelEdit() {
self.navigationItem.setRightBarButton(editActionBar, animated: true)
}
I also tried to use main thread as well but it is not working as I expected.
When you create a UIBarButtonItem as instance property the target self won't be initialized yet. So setting the target self won't work.
class ViewController: UIViewController {
let editActionBar = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editBtnAction(_:)))
override func viewDidLoad() {
super.viewDidLoad()
print(editActionBar.target)//nil
}
}
The target self will be assigned properly when you initialize the button in viewDidLoad
class ViewController: UIViewController {
var editActionBar: UIBarButtonItem?
override func viewDidLoad() {
super.viewDidLoad()
editActionBar = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editBtnAction(_:)))
print(editActionBar?.target)//self
}
}
Declare the buttons as optional and initialize the buttons in viewDidLoad.
class ViewController: UIViewController {
var editActionBar: UIBarButtonItem?
var cancelActionBar: UIBarButtonItem?
override func viewDidLoad() {
super.viewDidLoad()
self.editActionBar = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editBtnAction(_:)))
self.cancelActionBar = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelBtnAction(_:)))
self.navigationItem.setRightBarButton(editActionBar, animated: true)
}
#objc func editBtnAction(_ sender: UIBarButtonItem) {
self.navigationItem.setRightBarButton(cancelActionBar, animated: true)
}
#objc func cancelBtnAction(_ sender: UIBarButtonItem) {
self.navigationItem.setRightBarButton(editActionBar, animated: true)
}
}
In viewDidLoad method set edit as bar button
override func viewDidLoad() {
self.setBarButton(isSetEditBarButton: true)
}
#objc func editProfile() {
self.setBarButton(isSetEditBarButton: false)
}
#objc func cancelEdit() {
self.setBarButton(isSetEditBarButton: true)
}
private func setBarButton(isSetEditBarButton: Bool) {
if isSetEditBarButton {
let editActionBar = UIBarButtonItem(image: UIImage(named: "edit"), style: .plain, target: self, action: #selector(editProfile))
self.navigationItem.setRightBarButton(editActionBar, animated: true)
} else {
let cancelActionBar = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelEdit))
self.navigationItem.setRightBarButton(cancelActionBar, animated: true)
}
}

Pass a selector into an an extension

I am trying to tidy up a ViewController and would like to move the setup of a navigation item to an extension.
This is the code I am looking to move out of the ViewController:
private func setupNavigationItem() {
navigationItem.leftBarButtonItem = UIBarButtonItem.stashWhite(barButtonSystemItem: .cancel, target: self, selector: #selector(cancelBarButtonHandler))
navigationItem.rightBarButtonItem = UIBarButtonItem.stashRed(barButtonSystemItem: .save, target: self, selector: #selector(saveBarButtonItemHandler))
navigationItem.rightBarButtonItem?.isEnabled = false
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
I have then created this extension.
extension UINavigationItem {
func addSavingSetup(_ cancelBarButtonHandler: Selector, _ saveBarButtonItemHandler: Selector) {
leftBarButtonItem = UIBarButtonItem.stashWhite(barButtonSystemItem: .cancel, target: self, selector: cancelBarButtonHandler)
rightBarButtonItem = UIBarButtonItem.stashRed(barButtonSystemItem: .save, target: self, selector: saveBarButtonItemHandler)
rightBarButtonItem?.isEnabled = false
backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
}
I then call it like so:
navigationItem.addSavingSetup(#selector(cancelBarButtonHandler(_:)), #selector(saveBarButtonItemHandler))
However I then get this error when tapping either the cancel or save bar button:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationItem cancelBarButtonHandler:]: unrecognized selector sent to instance 0x105e01e80
Any idea how I can solve this? Not sure how else to pass in the selector.
Thanks
You are setting different target. you need to pass target, like below
extension UINavigationItem {
func addSavingSetup(target: Any,_ cancelBarButtonHandler: Selector, _ saveBarButtonItemHandler: Selector) {
leftBarButtonItem = UIBarButtonItem.stashWhite(barButtonSystemItem: .cancel, target: target, selector: cancelBarButtonHandler)
rightBarButtonItem = UIBarButtonItem.stashRed(barButtonSystemItem: .save, target: target, selector: saveBarButtonItemHandler)
rightBarButtonItem?.isEnabled = false
backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
}

Why does UIButton target only work when selector is declared in a certain way

I am really confused as to why the follow only works when I create the UIButton in view did load, Im hoping to get an answer to this because im trying to clean my the viewDidLoad function.
let logoutButton: UIBarButtonItem = {
let button = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = logoutButton // Does not work
// navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
}

Why setting the barItems is not working?

I have a UIViewController, and I embed it into a UINavigationController.
I want to show one item in the toolbar (and by toolbar, I mean this:
This is my code in viewDidLoad method
self.navigationController?.toolbarHidden = false
self.navigationController?.toolbar.items?.append(UIBarButtonItem(title: "Buy Potato", style: .Plain, target: self, action: #selector(ViewController.buyPotato)))
self.navigationController?.toolbarItems?.append(UIBarButtonItem(title: "Buy Potato", style: .Plain, target: self, action: #selector(ViewController.buyPotato)))
self.toolbarItems?.append(UIBarButtonItem(title: "Buy Potato", style: .Plain, target: self, action: #selector(ViewController.buyPotato)))
and I already have the method buyPotato
func buyPotato() {
}
as you see, I tried to do that using either the viewController or the navigationController, but it doesn't work.
All I can see is the toolbar at the bottom of my screen but without any button.
self.navigationController?.toolbarHidden = false
var items = [UIBarButtonItem]()
items.append(
UIBarButtonItem(barButtonSystemItem: .Plain, target: self, action: nil))
items.append(
UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "onClickedToolbeltButton:"))
self.setToolbarItems(barButtonItems, animated: true)
This has to work for you as per the answer written here.
Delete
self.setToolbarItems(barButtonItems, animated: true)
Add
self.toolbarItems = barButtonItems

Add a left bar button item to UINavigationController when no back button is present

I'd like to add a default left bar button item to my navigation bar. It should only display when there is no back button supplied by the UINavigationController.
What is the best approach?
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if(navigationController.viewControllers.count != 1) { // not the root controller - show back button instead
return;
}
UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemOrganize
target:self
action:#selector(menuItemSelected:)];
[viewController.navigationItem setLeftBarButtonItem:menuItem];
}
Swift code to add leftBarButtonItem…
let leftMenuItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action: "leftMenuItemSelected:");
self.navigationItem.setLeftBarButtonItem(leftMenuItem, animated: false);
Update
For Swift 4 & above
let leftMenuItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(leftMenuItemSelected(_:)))
self.navigationItem.setLeftBarButton(leftMenuItem, animated: false);
Swift 3 version:
let done = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(YourController.done))
navigationItem.setLeftBarButtonItem(done, animated: false)
For Swift 4.x and later(5.x)
func addNavigationItemBtn(){
let backBtn = UIBarButtonItem.init(title: "Menu", style: .plain, target: self, action: #selector(menuAction))
self.navigationItem.leftBarButtonItem = backBtn
}
#objc func menuAction(){
print("menu button pressed") //Do your action here
}
Swift 4
let item = UIBarButtonItem(title: "Setting", style: .done, target: self, action: #selector(setting))
navigationItem.rightBarButtonItem = item
// then do your action in function setting
#objc
final func setting() {
print("Your work here.")
}

Resources