iOS rightBarButtonItem on UINavigationController in swift - ios

I'm trying to put a rightBarButtonItem on a second view controller of an UINavigationViewController stack.
I'm creating and setting the button in viewDidLoad of the view controller that I want to show. My actual code looks like this:
override func viewDidLoad() {
super.viewDidLoad()
menu_button_ = UIBarButtonItem(image: UIImage(named: "menu"),
style: UIBarButtonItemStyle.Plain ,
target: self, action: "OnMenuClicked:")
self.navigationController!.navigationItem.rightBarButtonItem = menu_button_
}
What am I missing? The button doesn't appear.

You should set the menu_button_ as the rightBarButtonItem of your viewController rather than the navigationController.
Try
self.navigationItem.rightBarButtonItem = menu_button_
instead of
self.navigationController!.navigationItem.rightBarButtonItem = menu_button_

try with following code. it works for me.
let homeButton : UIBarButtonItem = UIBarButtonItem(title: "LeftButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: "")
let logButton : UIBarButtonItem = UIBarButtonItem(title: "RigthButtonTitle", style: UIBarButtonItemStyle.Plain, target: self, action: "")
self.navigationItem.leftBarButtonItem = homeButton
self.navigationItem.rightBarButtonItem = logButton
And if you want to settle out custom image then please check with apple guidelines on below link.
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/BarIcons.html#//apple_ref/doc/uid/TP40006556-CH21-SW1

In Swift 5
//For righter button item
let rightBtn = UIBarButtonItem(image: UIImage(named: "rightmenu"), style: .plain, target: self, action: #selector(onClickMethod))//Change your function name and image name here
self.navigationItem.rightBarButtonItem = rightBtn
//self.navigationItem.rightBarButtonItem = [rightBtn, anotherBtn] //If you want to add more buttons add like this
//This is your function
#objc func onClickMethod() {
print("Left bar button item")
}

Create an extension of UINavigationItem like -
extension UINavigationItem {
func addSettingButtonOnRight(){
let button = UIButton(type: .custom)
button.setTitle("setting", for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 15.0)
button.layer.cornerRadius = 5
button.backgroundColor = .gray
button.frame = CGRect(x: 0, y: 0, width: 100, height: 25)
button.addTarget(self, action: #selector(gotSettingPage), for: UIControlEvents.touchUpInside)
let barButton = UIBarButtonItem(customView: button)
self.rightBarButtonItem = barButton
}
#objc func gotSettingPage(){
}
}
And call it from viewDidLoad() like -
self.navigationItem.addSettingButtonOnRight()

Related

Design navigation bar in iOS swift

I want to design a navigation View like.
1. Left Menu , and title in center
2. Left Menu , and Image just next to it, and left side button
i am trying to add buttons like this , but button is not properly showing
func addMenuButton(){
let btn_menu = UIButton(frame: CGRect(x: 0, y: 0, width: 40, height: 44))
btn_menu.addTarget(self, action: #selector(self.refreshBtnClicked), for: .touchUpInside)
btn_menu.setImage(#imageLiteral(resourceName: "ic_menu"), for: .normal)
btn_menu.setImage(#imageLiteral(resourceName: "ic_menu"), for: .selected)
self.navigationController?.navigationItem.leftBarButtonItems = [UIBarButtonItem(customView: btn_menu)]
}
//Option 1
self.title = "Title Here"
self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "menu"), style: .plain, target: self, action: #selector(menuBtnAction(_:)))
//Option 2
let plusBtn = UIBarButtonItem(image: UIImage(named: "plus"), style: .plain, target: self, action: #selector(plusBtnAction(_:)))
let logoView = UIImageView(image: UIImage(named:"ins"))
logoView.translatesAutoresizingMaskIntoConstraints = false
logoView.widthAnchor.constraint(equalToConstant: 180).isActive = true
self.navigationItem.leftBarButtonItems = [plusBtn,UIBarButtonItem(customView: logoView)]
let titleLabel = UILabel()
titleLabel.text = "Main Controller"
titleLabel.frame = self.navigationController!.view.frame
titleLabel.textAlignment = .left
self.navigationItem.titleView = titleLabel
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(tapped))
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(tapped))
Try like this
func addMenuButton(){
let leftBarButtonItem : UIBarButtonItem? = UIBarButtonItem(image: #imageLiteral(resourceName: "ic_menu"), style: UIBarButtonItem.Style.plain, target: self, action: #selector(refreshBtnClicked))
self.navigationController?.navigationItem.leftBarButtonItem = leftBarButtonItem;
}

iOS toolbar barbuttonitem spacer

I am trying to add two bar buttons to toolbar in iOS [Cancel] & [Save] on right and left side accordingly.
I used a third bar button [Spacer] and set it to be [.flexiblewidth] Otherwise, when adding it only the left button appears [Cancel] and the [Spacer] & and [Save] which have to be next disappearing ?
the screen shot is in the link:
https://ibb.co/cZsaVV
let pickerView = UIPickerView()
override func viewDidLoad() {
pickerView.addSubview(self.setToolBar())
}
func setToolBar() -> UIToolbar {
let toolBar = UIToolbar()
toolBar.isTranslucent = true
toolBar.backgroundColor = UIColor.clear
let barButtonAttr = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 15),
NSAttributedString.Key.foregroundColor : UIColor.black]
// [Save] BarButtonItem
let saveBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.save, target: self, action: nil)
saveBarButtonItem.setTitleTextAttributes(barButtonAttr, for: .normal)
// [Cancel] BarButtonItem
let cancelBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.cancel, target: self, action: nil)
cancelBarButtonItem.setTitleTextAttributes(barButtonAttr, for: .normal)
let spacerBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace ,
target: self, action: nil)
spacerBarButtonItem.setTitleTextAttributes(barButtonAttr, for: .normal)
// add BarButtonItems to toolBar
toolBar.items = [cancelBarButtonItem,spacerBarButtonItem,saveBarButtonItem]
toolBar.sizeToFit()
return toolBar
}
func createAccessoryViewWithTarget(_ target: AnyObject, width: CGFloat) -> UIView {
// Previous button
let previousButton = UIBarButtonItem(title: "Previous", style: .plain, target: target, action: #selector(self.moveToPreviousTextField))
previousButton.tintColor = UIColor.white
//Next button
let nextButton = UIBarButtonItem(title: "Next", style: .plain, target: target, action: #selector(self.moveToNextTextField))
nextButton.tintColor = UIColor.white
// Dismiss/close/done button
let doneButton = UIBarButtonItem(title: "Done", style: .done, target: target, action: #selector(self.keyboardDoneButtonTapped))
doneButton.tintColor = UIColor.white
let keyboardToolbar: UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: width, height: 44))
keyboardToolbar.barStyle = .black
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let fixedSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
var itemsArray = [UIBarButtonItem]()
itemsArray.append(previousButton)
itemsArray.append(fixedSpace)
itemsArray.append(nextButton)
itemsArray.append(flexSpace)
itemsArray.append(doneButton)
keyboardToolbar.items = itemsArray
keyboardToolbar.sizeToFit()
return keyboardToolbar
}
This one is old code may be swift3 I guess. Here Im adding 3 buttons previous next and done button. flexible space and fixed space are used for spaces between buttons. Important to note here is the order that you adding your barbutton items. In your case use flexible space to place your 2 buttons on right and left end in the order of left end button, flexible space, right end button.
I've got the solution finally.
I am adding the ToolBar to the PickerView and then calling UIToolBar.SizeToFit() which is must in all cases.
the issue was I had to change the picker view size later in this case the size of subview ToolBar is not adapting with the new size coordination of pickerView. So the solution simply to call again ToolBar.SizeToFit() after any modification of parent view. here's snap of the code:
// popupView is custom UIPickerView
popupView.frame = CGRect(x:0, y:0, width:100, height:100)
// toolBar is an object of UIToolBar of the custom UIPickerView AddCurrencyPicker
(popupView as! AddCurrencyPicker).toolBar.sizeToFit()

Custom button in navigation bar - added and gets tapped but not visible

I try to add custom back button in navigation controller. I create button like this
func setupBackButton() {
let backButton = UIButton.init(type: .custom)
backButton.addTarget(self, action: #selector(backButtonHandler(_:)), for: .touchUpInside)
backButton.setTitleColor(UIColor.white, for: .normal)
backButton.setTitle("<", for: .normal)
backButton.tintColor = UIColor.white
let barBackButton = UIBarButtonItem(customView: backButton)
self.navigationItem.leftBarButtonItem = barBackButton
}
The problem is that button is being added (I can tap it and action on button is being executed) but i can't see button in controller - it is invisible.
Controller's color is blue.
you missed the frame of your button
backButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
dont forget to add the action handler
func backButtonHandler(_ sender : UIButton) {
}
try this :
func setupBackButton(){
let backBtn : UIBarButtonItem = UIBarButtonItem(title: "<", style: UIBarButtonItemStyle.plain, target: self, action:#selector(backToPreviousVC))
self.navigationItem.leftBarButtonItem = backBtn
backBtn.tintColor = UIColor.white
}
func backToPreviousVC() {
self.navigationController?.popViewController(animated: true)
}
call setupBackButton() in viewDidLoad

How to add multiple UIBarButtonItems on right side of Navigation Bar?

I would like to have more than a single UIBarButtonItem on the right side of my UINavigationBar. How can I achieve this?
An example of what I am trying are shown below - you can notice that the top right has more than one button.
Use this in swift:
override func viewDidLoad() {
super.viewDidLoad()
let editImage = UIImage(named: "plus")!
let searchImage = UIImage(named: "search")!
let editButton = UIBarButtonItem(image: editImage, style: .Plain, target: self, action: "didTapEditButton:")
let searchButton = UIBarButtonItem(image: searchImage, style: .Plain, target: self, action: "didTapSearchButton:")
navigationItem.rightBarButtonItems = [editButton, searchButton]
}
Write the action functions like this:
func didTapEditButton(sender: AnyObject){
...
}
func didTapSearchButton(sender: AnyObject){
...
}
Swift 4 & 5
override func viewDidLoad() {
super.viewDidLoad()
let editImage = UIImage(named: "edit")!
let searchImage = UIImage(named: "search")!
let editButton = UIBarButtonItem(image: editImage, style: .plain, target: self, action: #selector(didTapEditButton(sender:)))
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(didTapSearchButton(sender:)))
navigationItem.rightBarButtonItems = [editButton, searchButton]
}
#objc func didTapEditButton(sender: AnyObject){
}
#objc func didTapSearchButton(sender: AnyObject){
}
-(void)viewDidLoad{
UIBarButtonItem *anotherButton1 = [[UIBarButtonItem alloc] initWithTitle:#"Button_1" style:UIBarButtonItemStylePlain target:self action:#selector(button_1:)];
UIBarButtonItem *anotherButton2 = [[UIBarButtonItem alloc] initWithTitle:#"Button_" style:UIBarButtonItemStylePlain target:self action:#selector(button_2:)];
self.navigationItem.rightBarButtonItems=#[anotherButton1,anotherButton2];
}
In Swift 3 you can use:
let editImage = UIImage(named: "plus")!
let searchImage = UIImage(named: "search")!
let editButton = UIBarButtonItem(image: editImage, style: .plain, target: self, action: #selector(didTapEditButton))
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(didTapSearchButton))
navigationItem.rightBarButtonItems = [editButton, searchButton]
I think nothing of the above is going to work
Try this
var burgerItem = UIBarButtonItem(image: UIImage(named:"categories"), style: .Plain, target: self, action: "categories")
var weatherItem = UIBarButtonItem(title: "Weather", style: .Plain, target: self, action: "weather")
burgerItem.tintColor = UIColor.whiteColor()
weatherItem.tintColor = UIColor.whiteColor()
navigationItem.setRightBarButtonItems([burgerItem,weatherItem], animated: true)
You have to use navigationItem.setRightBarButtonItems and be carefull. navigationItem has to be of a view controller.
class testViewController:UIViewController {
ovverride func viewDidLoad() {
self.navigationItem.setRightBarButtonItems(...
}
}
Simply add this code:
self.navigationItem.leftBarButtonItem = nil
let button = UIButton(type: .custom)
button.setImage(UIImage (named: "ChatTab"), for: .normal)
button.frame = CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0)
//button.addTarget(target, action: nil, for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: button)
let button2 = UIButton(type: .custom)
button2.setImage(UIImage (named: "ActivityTab"), for: .normal)
button2.frame = CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0)
//button.addTarget(target, action: nil, for: .touchUpInside)
let barButtonItem2 = UIBarButtonItem(customView: button2)
self.navigationItem.rightBarButtonItems = [barButtonItem, barButtonItem2]
This is the result:
With Swift 4
let editImage = UIImage(named: "toolbar_edit")!
let favoriteImage = UIImage(named: "toolbar_fav_solid")!
let editButton = UIBarButtonItem(image: editImage, style: .plain, target: self, action: #selector(didTapEditButton))
let favoriteButton = UIBarButtonItem(image: favoriteImage, style: .plain, target: self, action: #selector(didTapFavoriteButton))
navigationItem.rightBarButtonItems = [editButton, favoriteButton]
Click action for those buttons
#objc func didTapEditButton(sender: AnyObject) {
print("edit")
}
#objc func didTapFavoriteButton(sender: AnyObject) {
print("favorite")
}
Output screenshot (iPhone X)
Accepted answer as well as few of the answer is absolutely correct but in my case none of them work.
Reason : My View Controller was Inherited from UIViewController and I had to set Add to Cart Button and Search Button On Right hand side. And All my view controllers were a part of UITabbarController.
let editImage = UIImage(named: "OrdersTabIcon")
let searchImage = UIImage(named: "OrdersTabIcon")
let editButton = UIBarButtonItem(image: editImage, style: .plain, target: self, action: #selector(iconTapped))
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(iconTapped))
Instead of using
self.navigationItem.setRightBarButtonItems([editButton, searchButton], animated: true)
Use This .
self.navigationController?.navigationBar.topItem?.setRightBarButtonItems([editButton, searchButton], animated: true)
This is may be help for you in objective-c,
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.navigationItem.title = #"Title";
UIBarButtonItem *logOutButton = [[UIBarButtonItem alloc] initWithTitle:#"Logout" style:UIBarButtonItemStylePlain target:self action:#selector(ButtonClickedAtIndex1:)];
[logOutButton setTintColor:[UIColor blackColor]];
logOutButton.tag = 1;
UIBarButtonItem *syncBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Sync" style:UIBarButtonItemStylePlain target:self action:#selector(ButtonClickedAtIndex1:)];
[syncBarButtonItem setTintColor:[UIColor blackColor]];
syncBarButtonItem.tag = 2;
self.navigationItem.leftBarButtonItem = logOutButton;
self.navigationItem.rightBarButtonItem = syncBarButtonItem;
float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0) {
self.edgesForExtendedLayout = UIRectEdgeNone;
self.navigationController.navigationBar.translucent = NO;
}
}
return self;
}
Use navigationItem's rightBarButtonItems, which takes an array of UIBarButton. Appledoc
let share = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareTapped))
let add = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addTapped))
navigationItem.rightBarButtonItems = [add, share]
I don't know wether an Interface Builder solution was not possible before, but at least with the most recent update (Xcode 11.0), it is possible to drag two UI Bar Buttons into the rightBarButton space. Two outlets and actions can then be dragged into the code like always.
Since the OP didn't ask for a solution without IB, I think this also qualifies as an answer.
For Xamarin iOS with the new updates, it is like:
UIBarButtonItem Button1 = new UIBarButtonItem(UIImage.FromBundle("Image1"), UIBarButtonItemStyle.Plain,YourEventHandler);
UIBarButtonItem Button2 = new UIBarButtonItem(UIImage.FromBundle("Image1"), UIBarButtonItemStyle.Plain,YourEventHandler);
NavigationItem.SetRightBarButtonItems(new[]{ Button1, Button2 }, true);

UIBarButtonItem in navigation bar programmatically?

I've been looking around for this solution for a while but haven't got any.
e.g one solution is
self.navigationItem.setRightBarButtonItem(UIBarButtonItem(barButtonSystemItem: .Stop, target: self, action: nil), animated: true)
This code will add a button with "stop" image. Just like this, there are other solutions with "search, "refresh" etc. But what if I want to add a button programmatically with the image I want?
Custom button image without setting button frame:
You can use init(image: UIImage?, style: UIBarButtonItemStyle, target: Any?, action: Selector?) to initializes a new item using the specified image and other properties.
let button1 = UIBarButtonItem(image: UIImage(named: "imagename"), style: .plain, target: self, action: Selector("action")) // action:#selector(Class.MethodName) for swift 3
self.navigationItem.rightBarButtonItem = button1
Check this Apple Doc. reference
UIBarButtonItem with custom button image using button frame
FOR Swift 3.0
let btn1 = UIButton(type: .custom)
btn1.setImage(UIImage(named: "imagename"), for: .normal)
btn1.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btn1.addTarget(self, action: #selector(Class.Methodname), for: .touchUpInside)
let item1 = UIBarButtonItem(customView: btn1)
let btn2 = UIButton(type: .custom)
btn2.setImage(UIImage(named: "imagename"), for: .normal)
btn2.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btn2.addTarget(self, action: #selector(Class.MethodName), for: .touchUpInside)
let item2 = UIBarButtonItem(customView: btn2)
self.navigationItem.setRightBarButtonItems([item1,item2], animated: true)
FOR Swift 2.0 and older
let btnName = UIButton()
btnName.setImage(UIImage(named: "imagename"), forState: .Normal)
btnName.frame = CGRectMake(0, 0, 30, 30)
btnName.addTarget(self, action: Selector("action"), forControlEvents: .TouchUpInside)
//.... Set Right/Left Bar Button item
let rightBarButton = UIBarButtonItem()
rightBarButton.customView = btnName
self.navigationItem.rightBarButtonItem = rightBarButton
Or simply use init(customView:) like
let rightBarButton = UIBarButtonItem(customView: btnName)
self.navigationItem.rightBarButtonItem = rightBarButton
For System UIBarButtonItem
let camera = UIBarButtonItem(barButtonSystemItem: .Camera, target: self, action: Selector("btnOpenCamera"))
self.navigationItem.rightBarButtonItem = camera
For set more then 1 items use rightBarButtonItems or for left side leftBarButtonItems
let btn1 = UIButton()
btn1.setImage(UIImage(named: "img1"), forState: .Normal)
btn1.frame = CGRectMake(0, 0, 30, 30)
btn1.addTarget(self, action: Selector("action1:"), forControlEvents: .TouchUpInside)
let item1 = UIBarButtonItem()
item1.customView = btn1
let btn2 = UIButton()
btn2.setImage(UIImage(named: "img2"), forState: .Normal)
btn2.frame = CGRectMake(0, 0, 30, 30)
btn2.addTarget(self, action: Selector("action2:"), forControlEvents: .TouchUpInside)
let item2 = UIBarButtonItem()
item2.customView = btn2
self.navigationItem.rightBarButtonItems = [item1,item2]
Using setLeftBarButtonItem or setRightBarButtonItem
let btn1 = UIButton()
btn1.setImage(UIImage(named: "img1"), forState: .Normal)
btn1.frame = CGRectMake(0, 0, 30, 30)
btn1.addTarget(self, action: Selector("action1:"), forControlEvents: .TouchUpInside)
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: btn1), animated: true);
For swift >= 2.2 action should be #selector(Class.MethodName) ... for e.g. btnName.addTarget(self, action: #selector(Class.MethodName), forControlEvents: .TouchUpInside)
It's much easier with Swift 4 or Swift 4.2
inside your ViewDidLoad method, define your button and add it to the navigation bar.
override func viewDidLoad() {
super.viewDidLoad()
let logoutBarButtonItem = UIBarButtonItem(title: "Logout", style: .done, target: self, action: #selector(logoutUser))
self.navigationItem.rightBarButtonItem = logoutBarButtonItem
}
then you need to define the function that you mentioned inside action parameter as below
#objc func logoutUser(){
print("clicked")
}
You need to add the #objc prefix as it's still making use of the legacy stuff (Objective C).
Just setup UIBarButtonItem with customView
For example:
var leftNavBarButton = UIBarButtonItem(customView:yourButton)
self.navigationItem.leftBarButtonItem = leftNavBarButton
or use setFunction:
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(customView: yourButton), animated: true);
I just stumbled upon this question and here is an update for Swift 3 and iOS 10:
let testUIBarButtonItem = UIBarButtonItem(image: UIImage(named: "test.png"), style: .plain, target: self, action: nil)
self.navigationItem.rightBarButtonItem = testUIBarButtonItem
It is definitely much faster than creating the UIButton with all the properties and then subsequently adding the customView to the UIBarButtonItem.
And if you want to change the color of the image from the default blue to e.g. white, you can always change the tint color:
test.tintColor = UIColor.white()
PS You should obviously change the selector etc. for your app :)
In Swift 3.0+, UIBarButtonItem programmatically set up as follows:
override func viewDidLoad() {
super.viewDidLoad()
let testUIBarButtonItem = UIBarButtonItem(image: UIImage(named: "test.png"), style: .plain, target: self, action: #selector(self.clickButton))
self.navigationItem.rightBarButtonItem = testUIBarButtonItem
}
#objc func clickButton(){
print("button click")
}
FOR Swift 5+
let searchBarButtonItem = UIBarButtonItem(image: UIImage(named: "searchIcon"), style: .plain, target: self, action: #selector(onSearchButtonClicked))
self.navigationItem.rightBarButtonItem = searchBarButtonItem
#objc func onSearchButtonClicked(_ sender: Any){
print("SearchButtonClicked")
}
Setting LeftBarButton with Original Image.
let menuButton = UIBarButtonItem(image: UIImage(named: "imagename").withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(classname.functionname))
self.navigationItem.leftBarButtonItem = menuButton
iOS 11
Setting a custom button using constraint:
let buttonWidth = CGFloat(30)
let buttonHeight = CGFloat(30)
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "img name"), for: .normal)
button.addTarget(self, action: #selector(buttonTapped(sender:)), for: .touchUpInside)
button.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
button.heightAnchor.constraint(equalToConstant: buttonHeight).isActive = true
self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: button)
I have same issue and I have read answers in another topic then I solve another similar way. I do not know which is more effective.
similar issue
//play button
#IBAction func startIt(sender: AnyObject) {
startThrough();
};
//play button
func startThrough() {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateTime"), userInfo: nil, repeats: true);
let pauseButton = UIBarButtonItem(barButtonSystemItem: .Pause, target: self, action: "pauseIt");
self.toolBarIt.items?.removeLast();
self.toolBarIt.items?.append( pauseButton );
}
func pauseIt() {
timer.invalidate();
let play = UIBarButtonItem(barButtonSystemItem: .Play, target: self, action: "startThrough");
self.toolBarIt.items?.removeLast();
self.toolBarIt.items?.append( play );
}
This is a crazy thing of apple. When you say self.navigationItem.rightBarButtonItem.title then it will say nil while on the GUI it shows Edit or Save. Fresher likes me will take a lot of time to debug this behavior.
There is a requirement that the Item will show Edit in the firt load then user taps on it It will change to Save title. To archive this, i did as below.
//view did load will say Edit title
private func loadRightBarItem() {
let logoutBarButtonItem = UIBarButtonItem(title: "Edit", style: .done, target: self, action: #selector(handleEditBtn))
self.navigationItem.rightBarButtonItem = logoutBarButtonItem
}
// tap Edit item will change to Save title
#objc private func handleEditBtn() {
print("clicked on Edit btn")
let logoutBarButtonItem = UIBarButtonItem(title: "Save", style: .done, target: self, action: #selector(handleSaveBtn))
self.navigationItem.rightBarButtonItem = logoutBarButtonItem
blockEditTable(isBlock: false)
}
//tap Save item will display Edit title
#objc private func handleSaveBtn(){
print("clicked on Save btn")
let logoutBarButtonItem = UIBarButtonItem(title: "Edit", style: .done, target: self, action: #selector(handleEditBtn))
self.navigationItem.rightBarButtonItem = logoutBarButtonItem
saveInvitation()
blockEditTable(isBlock: true)
}
addition to the above you may use the following for ios14 and above
if #available(iOS 14.0, *) {
let closeAction = UIAction(handler: { [weak self] _ in
//perform action here
})
let closeBarButtonItem = UIBarButtonItem(systemItem: .close, primaryAction: closeAction, menu: nil)
navigationItem.rightBarButtonItem = closeBarButtonItem
}
func viewDidLoad(){
let homeBtn: UIButton = UIButton(type: UIButtonType.custom)
homeBtn.setImage(UIImage(named: "Home.png"), for: [])
homeBtn.addTarget(self, action: #selector(homeAction), for: UIControlEvents.touchUpInside)
homeBtn.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
let homeButton = UIBarButtonItem(customView: homeBtn)
let backBtn: UIButton = UIButton(type: UIButtonType.custom)
backBtn.setImage(UIImage(named: "back.png"), for: [])
backBtn.addTarget(self, action: #selector(backAction), for: UIControlEvents.touchUpInside)
backBtn.frame = CGRect(x: -10, y: 0, width: 30, height: 30)
let backButton = UIBarButtonItem(customView: backBtn)
self.navigationItem.setLeftBarButtonItems([backButton,homeButton], animated: true)
}
}

Resources