Change Navigation Bar Item Dynamically - Swift - ios

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)
}
}

Related

How do I get the back bar button item to show up in my navigation item in iOS?

I am not able to show a back bar button item in my navigation item in my root view controller of my navigation controller.
I have tried setting different properties.
Other questions like this do not give me an answer that works.
Her is my code in my root view controller:
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad")
navigationItem.leftItemsSupplementBackButton = true
navigationItem.backBarButtonItem = UIBarButtonItem(title: "Button", style: .plain, target: nil, action: nil)
navigationItem.setHidesBackButton(false, animated: true)
navigationItem.leftItemsSupplementBackButton = true
}
Assigning to leftBarButtonItem instead of backBarButtonItem works for me:
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad")
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Button", style: .plain, target: nil, action: nil)
}

How to present popUp when user taps on right bar button item?

I'm relatively new at iOS. I'm struggling, for a while now with this issue. I don't know how to set the logic for presenting popUp when user taps on right bar button item. Basically, it should look like this:PopUp I searched through Google, but I didn't have any luck. I would appreciate if someone would help me with some code.
//My VC
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let rightBarButtonItem = UIBarButtonItem(title: "Share", style: .plain, target: self, action: #selector(clickShare))
rightBarButtonItem.tintColor = UIColor.black
navigationItem.rightBarButtonItem = rightBarButtonItem
// navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Share", style: UIBarButtonItemStyle.plain, target: self, action: #selector(clickShare))
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "backArrow"), style: UIBarButtonItemStyle.plain, target: self, action: #selector(goBack))
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font : UIFont(name: "OpenSans", size: 14)! ], for: .normal)
}
//MARK: - Actions
#objc func goBack() {
navigationController?.popViewController(animated: true)
}
#objc func clickShare() {
//this is where the logic should go
}
//This is my storyboard:
Storyboard
Add following action,
#IBAction func yourButtonClickAction(sender: UIBarButtonItem) {
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("YourViewController") as! UIViewController
vc.modalPresentationStyle = UIModalPresentationStyle.Popover
let popover: UIPopoverPresentationController = vc.popoverPresentationController!
popover.barButtonItem = sender
popover.delegate = self
presentViewController(vc, animated: true, completion:nil)
}
Add this action to you barButtonItem.
'YourViewController' = controller consisting of Public, followers options.

setting a UIBarButtonItem to backBarButtonItem with an action, does not work

When I assign the following UIBarButtonItem to backBarButtonItem I get a button with the title I assigned, but the action is never called.
Using leftBarButtonItem instead, will add a button and the action will be called. What is overriding my action? Can I do something about it?
override func viewDidLoad() {
super.viewDidLoad()
let backItem = UIBarButtonItem(title: "Back",
style: .plain,
target: self,
action: #selector(backNavigationClick))
navigationItem.backBarButtonItem = backItem
}
#objc func backNavigationClick() {
print("back clicked")
}
if you use it in this way you can customize the button.
You need to replace this code
navigationItem.backBarButtonItem = backItem
to
navigationItem.leftBarButtonItem = backItem
and add this code on backNavigationClick()
#objc func backNavigationClick() {
print("back clicked")
self.navigationController?.popViewController(animated: true) ***
}

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))
}

Hide back button in tabbar navigation controller

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

Resources