How do I adjust the position of a UIBarButtonItem - ios

I need to adjust the vertical position of my UIBarButtonItems.
I seem to be able to do it for the title just fine but the buttons don't seem to go along with it. What am I doing wrong?
var leftBarButtonItem : UIBarButtonItem?
leftBarButtonItem
= UIBarButtonItem(title: "", style: .done, target: self, action: #selector(self.leftBarButtonPressed(_:)))
leftBarButtonItem?.image = UIImage(named: "menu_ic")
self.navigationItem.leftBarButtonItem = leftBarButtonItem
self.navigationController?.navigationItem.leftBarButtonItem?.setBackgroundVerticalPositionAdjustment(CGFloat(18), for: UIBarMetrics.default)
var rightBarButtonItem : UIBarButtonItem?
rightBarButtonItem
= UIBarButtonItem(title: "MAP", style: .done, target: self, action:
#selector(self.rightBarButtonPressed(_:)))
self.navigationItem.rightBarButtonItem = rightBarButtonItem
let height: CGFloat = 60 //sets height of UINavigationBar
let bounds = self.navigationController!.navigationBar.bounds
self.navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height + height)
self.navigationController!.navigationBar.setTitleVerticalPositionAdjustment(CGFloat(18), for: UIBarMetrics.default)

Related

navigation bar button item is bigger than the frame i set

I don't know what's wrong with my code or what did I did that leads to this I spent half an hour trying to figure out what's wrong with my code but I have no idea, I'm calling this func in viewDidLoad()
func setupNavBarBtn(){
let backBtn = UIButton(type: .system)
backBtn.setImage(#imageLiteral(resourceName: "cellarrow").withRenderingMode(.alwaysOriginal), for: .normal)
backBtn.contentMode = .scaleAspectFit
backBtn.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
let callBtn = UIButton(type: .system)
callBtn.setImage(#imageLiteral(resourceName: "Call").withRenderingMode(.alwaysOriginal), for: .normal)
callBtn.contentMode = .scaleAspectFit
callBtn.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
self.navigationItem.leftBarButtonItems = [UIBarButtonItem(customView: backBtn), UIBarButtonItem(customView: callBtn)]
}
You should create UIBarButtonItem instead of UIButton:
let backBtn = UIBarButtonItem(image:UIImage(named: "cellarrow.png"), style: .plain, target: nil, action: nil)
let callBtn = UIBarButtonItem(image:UIImage(named: "Call.png"), style: .plain, target: nil, action: nil)
self.navigationItem.leftBarButtonItems = [backBtn,callBtn]
The size of bar button should better be 20x20

Navigation Bar Items not left aligned

I have a navigationBar where I would like to have a button on the left, a activityIndicator as title and a doneButton on the right. This is what I tried:
let activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 25, height: 25))
let googleImage = UIImage(named: "google")!
let googleButton = UIBarButtonItem(image: googleImage, style: .plain, target: self, action: #selector(googleButtonTapped))
googleButton.image = UIImage(named: "google")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
navigationController?.navigationBar.barTintColor = UIColor.blueCustom
navigationController?.navigationBar.tintColor = UIColor.white
activityIndicator.hidesWhenStopped = true
activityIndicator.color = .white
self.navigationItem.titleView = self.activityIndicator
self.navigationItem.leftBarButtonItem = googleButton
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Fertig", style: .done, target: self, action: #selector(doneTapped))
The problem is that googleButton and activityIndicator are not on the left/center:
What am I missing here?
Update:
I tried setting the leftBarButtonItem to a simple item with title and it works as expexted.. Why is it not working with the image?
I think it has to do with the intrinsicContentSize of the googleButton. Since you haven't explicitly set it, the size of the google logo image is expanding the width of the button. The intrinsicContentSize property of a UIButton has a set height by default, but none for the width:
let googleImage = UIImage(named: "google")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal).resizeTo(size: CGSize(width: 25, height: 25))
let googleButton = UIButton()
googleButton.setBackgroundImage(googleImage, for: .normal)
googleButton.addTarget(self, action: #selector(googleButtonTapped), for: .touchUpInside)
let googleBarButton = UIBarButtonItem(customView: googleButton)
You can create a UIImage extension to redraw the size of the google logo:
extension UIImage {
func resizeTo(size: CGSize) -> UIImage {
let renderer = UIGraphicsImageRenderer(size: size)
let image = renderer.image { _ in
self.draw(in: CGRect.init(origin: CGPoint.zero, size: size))
}
return image.withRenderingMode(self.renderingMode)
}
}
Change the button name to:
self.navigationItem.leftBarButtonItem = googleBarButton
Of course, the 25 points for the width and the height is arbitrary. Adjust it to fit your need.

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

First leftBarButtonItem is hiding

I used 2 bar button items. One is for back button and second is for the title. It is working fine. But when the title string is large, the title shifts to left and back button does not appear, but it is working.
I am also using a rightBarButtonItem, that is attached with a badge button. But that is not affecting this as I have tried the same code after removing that button. This is my code -
let backBtnImg: UIImage = UIImage(named: "Back Image")!
let Back: UIBarButtonItem = UIBarButtonItem(image: backBtnImg, style: .plain, target: self, action: #selector(backButtonAction))
let titleStr = ("titleString")
let titleItem: UIBarButtonItem = UIBarButtonItem(title: titleStr, style: .plain, target: nil, action: nil)
self.navigationItem.leftBarButtonItems = [Back, titleItem]
I have attached both the images.
Please try this code if you want to set the title in left side. It may helps to you.
In viewDidLoad method
let navView = UIView(frame: CGRect(x: 0, y: 0, width: (self.navigationController?.navigationBar.frame.size.width)! - 50, height: 40))
lblTitle = UILabel(frame: CGRect(x: 0, y: 0, width: navView.frame.size.width - 40, height: 40))
lblTitle?.text = strTitle
lblTitle?.backgroundColor = UIColor.clear
lblTitle?.textColor = UIColor.white
lblTitle?.textAlignment = .left
navView.addSubview(lblTitle!)
self.navigationItem.titleView = navView
Use this One It help you
-> take only one left button
-> For Title use: self.navigationItem.title = "Navigation Title"
let backBtnImg: UIImage = UIImage(named: "back")!
let Back: UIBarButtonItem = UIBarButtonItem(image: backBtnImg, style: .plain, target: self, action: #selector(backButtonAction))
self.navigationItem.title = "Navigation Title"
self.navigationItem.leftBarButtonItems = [Back]
func setupNevigationBar(){
let btnBack = UIButton(type: .custom)
btnBack.setImage(#imageLiteral(resourceName: "back"), for: .normal)
btnBack.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
btnBack.addTarget(self, action: #selector(btnBackPressed), for: .touchUpInside)
let itemBack = UIBarButtonItem(customView: btnBack)
let titleStr = ("Regular Title")
let titleItem: UIBarButtonItem = UIBarButtonItem(title: titleStr, style: .plain, target: nil, action: nil)
self.navigationItem.leftBarButtonItems = [itemBack, titleItem]
self.navigationItem.setLeftBarButton(itemBack, animated: true)
}

RightBarButtonItem is not displayed in the correct location

I am creating a UINavigationController programmatically and add my ViewController to it:
// wrap in a navigation controller
let navigationController = UINavigationController(rootViewController: myViewController)
self.present(navigationController, animated: true, completion: nil)
And then add an image to navigation item:
let backButton: UIBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: target, action: selector)
backButton.image = UIImage(named: "ic_back")
self.navigationItem.rightBarButtonItem = backButton
But my BarButton is not displayed in the correct location. What am I doing wrong?
You need to init UIBarButton directly to UIImage or Custom View:
i.e.,
Swift 3.0:
let image = UIImage(named: "ic_back")?.withRenderingMode(.alwaysOriginal)
let button = UIBarButtonItem(image: image, style: .plain, target: target, action: selector)
self.navigationItem.rightBarButtonItem = button
This will fix your issue.
alloc and init UIButton with desired frame! set image to that button. Set content mode if required! add target on this button to handle click! then alloc and init UIBarButtonItem using initWithCustomView method and pass UIButton as parameter that you have created.
Then set navigationItem's rightBarbuttonItem to this barbutton!
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)
self.navigationItem.setRightBarButtonItems(item1, animated: true)
You can set the button on navigation bar like this..
let Button = UIButton(frame: CGRect(x: 0, y: 0, width: 35, height: 40))
Button.setBackgroundImage(UIImage(named: "btn.png"), for: .normal)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: Button)
So this code is helps you to achieve your query
Add frame to your backButton using the following code and let us know if it worked.
backButton.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
You may change width and height acc. to your need.

Resources