Custom bar button item not sizing properly - ios

I have a custom app that includes a custom bar button item, with Swift 3 it was sized appropriately but after updating to Swift 4 it is no longer sizing to the constraints provided. This is my code:
let infoButton = UIButton.init(type: .custom)
infoButton.setImage(UIImage(named: "info button white.png"), for: UIControlState.normal)
infoButton.addTarget(self, action: #selector(StartViewController.infoButtonPressed), for: UIControlEvents.touchUpInside)
infoButton.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
let barButton = UIBarButtonItem(customView: infoButton)
self.navigationItem.rightBarButtonItem = barButton
I tried changing the CGRect numbers to see if there would be any change, and there is not, it is sizing to the limits of the navigation bar, and frankly now looks quite ugly.
Any ideas about what changed in Swift 4? I am running Xcode 9.0(9A235)

Try setting constraints like this:
infoButton.widthAnchor.constraint(equalToConstant: 25).isActive = true
infoButton.heightAnchor.constraint(equalToConstant: 25).isActive = true
Or use images of the correct size.

Related

UIBarButtonItem with custom UIButton is invisible on iOS <= 10

I need to create a "burger menu" button for my app on my navigationController's left side but since the NavCon is transparent I need to have a shadow on my icon.
Thus I've created a custom UIButton with an image, a drop shadow and the added it as a custom view on a UIBarButtonItem as follows:
let menuButton = UIButton(type: .custom)
menuButton.addTarget(self, action: #selector(showSideMenu), for: .touchUpInside)
menuButton.setImage(#imageLiteral(resourceName: "menu_white"), for: .normal)
menuButton.tintColor = UIColor.white
menuButton.layer.masksToBounds = false
menuButton.layer.shadowColor = UIColor.black.cgColor
menuButton.layer.shadowOpacity = 1.0
menuButton.layer.shadowRadius = 5
menuButton.layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: menuButton)
The code above works perfectly fine on iOS 11, but when I tested my app on ios 9 and 10 (both simulators and real devices) the menu icon is invisible. It is clickable and works as expected, but there is no visible icon.
In the View Hierarchy Debugger I can see a UIButton with 0 width and height, while in ios 11 I can see the normal UIButtonBarStackview with the embedded UIButton.
Any ideas on how to fix this and why this is happening? Thank you very much!
Please mention the button frame
let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: 40))
It may helps to you thank you
You can just call menuButton.sizeToFit() and it will work.

Create UIBarButtonItem with fixed size and with custom icon

I've created navigation bar like picture below
The "drop" button is a custom system UIBarButtonItem. It's contained in Right Bar Button Items and its area was expanded.
I want its size fit the image I set, like Compose button on the right.
public func setCustomButton() {
let btnSearch: UIButton = UIButton(type: .custom)
btnSearch.frame = CGRect(x: 0, y: 0, width: 25.0, height: 25.0)
btnSearch.setImage("Your image", for: .normal)
btnSearch.addTarget(self, action: #selector(yourActionName(_:)), for: .touchUpInside)
et btnBarButtonSearch: UIBarButtonItem = UIBarButtonItem(customView: btnSearch)
navigationItem.rightBarButtonItems = [btnBarButtonSearch]
}
hope, it will help you.

How to change the height and width of a button in iOS app using Swift 4.0 which is developed using Swift 3.0

I am completely new to iOS development and I am supposed to fix some bugs in an iOS app which is made using Swift 3.0 and Xcode 8 and it works almost fine. But when I open it with Xcode 9 and Swift 4.0 it shows some buttons way different that they were before.
Here is the source code for one of those buttons.
let button: UIButton = UIButton.init(type: UIButtonType.custom)
//set image for button
button.setImage(UIImage(named: "menu.png"), for: UIControlState())
button.frame = CGRect(x: 0, y: 0, width: 30, height: 23)
let barButton = UIBarButtonItem(customView: button)
button.addTarget(self, action: #selector(ViewController.shareButtonPressed), for: UIControlEvents.touchUpInside)
self.navigationItem.leftBarButtonItem = barButton
this code is inside the ViewDidLoad method. My problem is when I remove,
button.setImage(UIImage(named: "menu.png"), for: UIControlState())
it disappears the button but when I change the height and the width from,
button.frame = CGRect(x: 0, y: 0, width: 30, height: 23)
it changes nothing.
My problem is how can I fix this bug. Any suggestion, answer is highly appreciated and if the given details are not enough, please mention. Thank you!
Beginning with iOS 11, views added to toolbars using UIBarButtonItem using UIBarButtonItem(customView:) are now laid out using auto layout. You should add sizing constraints on your button. For example:
button.widthAnchor.constraintEqualToConstant(30.0).isActive = true
button.heightAnchor.constraintEqualToConstant(23.0).isActive = true
Otherwise, auto layout will use the intrinsic content size of your header view which is likely not what you expect.
For more information see the WWDC 2017 session Updating your app for iOS 11.
swift 4:
button.widthAnchor.constraint(equalToConstant: 30.0).isActive = true
button.heightAnchor.constraint(equalToConstant: 20.0).isActive = true
You can customize width and height of button using storyboard in Xcode. Just select your button and open this window.
After that just add the height constraints.

Adding a custom navigation bar covering content in screen

I have added a custom navigation bar via storyboard. I was expecting the content on the screen to automatically shift downward. but instead it completely covers content on the top of the screen.. is there a clean line of code that automatically creates that spacing between the navigation bar and the view itself?
You might have heard about Cocpods which i feel is a better way to go for cutsom Navigation bar.
You just need to implement the protocol and give the specifications you need for the Navigation bar
Go through the following cooped
https://cocoapods.org/pods/resizable-navigation-bar
Just call this method from viewDidLoad :
func createNavBar() {
let leftNavigationButton = UIButton()
leftNavigationButton.setImage(UIImage(named: "ic_back.png"), forState: .Normal)
leftNavigationButton.frame = CGRectMake(10, 10, 20, 15)
leftNavigationButton.addTarget(self, action: "onBackButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
let customBarItem = UIBarButtonItem(customView: leftNavigationButton)
self.navigationItem.leftBarButtonItem = customBarItem;
//set TitleAppIcon
let GR = UITapGestureRecognizer(target: self, action: Selector("headerLogoTapAction:"))
let imageView = UIImageView(frame: CGRect(x: 90, y: 0, width: ((UIScreen.mainScreen().bounds.width)/3), height: 40))
imageView.contentMode = .ScaleAspectFit
let image = UIImage(named: "yourimag.png") //or set title
imageView.image = image
imageView.addGestureRecognizer(GR)
imageView.userInteractionEnabled = true
navigationItem.titleView = imageView
}
Hope this gonna help you

Make the navigationbar title clickable swift

I would like to make the navigationbar title to be clickable. When user click on it, it should perform a segue. But I have no idea how to do this.
I have tried the following to get the title and apply the Tap gesture to it.
var subviews = self.navigationController?.navigationBar.subviews
if let subviews = subviews {
// Better check for array length before accessing to the 1st element
var subview = subviews [0]
}
but its giving me error Variable subview inferred to have type AvyObject, which may be unexpected
One more approach to add button as a title of navigation controller.
You need to set navigation item title view to your button object
Create button object in viewDidLoad() method:
Swift 4.0 Edit
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
button.backgroundColor = .red
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(clickOnButton), for: .touchUpInside)
navigationItem.titleView = button
Here you can see in last line button is directly set to the titleView of navigationItem which will add button at the center of navigation bar.
Action method for button is below:
#objc func clickOnButton() {
}
Kampai's answer updated for Swift 3:
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(self.clickOnButton), for: .touchUpInside)
self.navigationItem.titleView = button
To get rid of that error, specify a type for your if let constant. I'd also recommend changing that if let constant name since it's the same as the one already declared in the previous line.
var subviews = self.navigationController?.navigationBar.subviews
if let subviewArray:NSArray = subviews {
// Better check for array length before accessing to the 1st element
var subview:UILabel = subviewArray[0] // <-- If the subview's a UILabel
}

Resources