Adding a custom navigation bar covering content in screen - ios

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

Related

Circular UIBarButtonItem button image get stretched

Added circular button on self.navigationItem.leftBarButtonItem for specific UIViewController of a TabBarcontroller after switching one tab and getting back to specific tab. The circular button is stretched.
override func viewDidLoad() {
infoButton = UIButton(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
infoButton.sd_setBackgroundImage(with: URL(string: "https://www.w3schools.com/howto/img_avatar.png"), for: .normal)
infoButton.addTarget(self, action: #selector(menuButtonPressed), for: .touchUpInside)
infoButton.layer.cornerRadius = infoButton.bounds.size.width / 2
infoButton.clipsToBounds = true
infoButton.layer.borderWidth = 1.0
infoButton.imageView?.contentMode = .scaleToFill
infoButton.layer.borderColor = UIColor.init(hexString: "#AAC8FF").cgColor
let infoItem = UIBarButtonItem(customView: infoButton)
self.navigationItem.leftBarButtonItem = infoItem
}
Error Image:
You forgot to give infoButton a size. You have to use auto layout. Give it a width constraint with a constant 40 and a height constraint with a constant 40.

How to fit an image in rightbarbuttonitem

I've been trying to put a hamburger button (the three parallel lines) to the right of the titleView in the nav bar, but every time I do, the image I put in covers the entire nav bar and gets rid of the image I have in titleView.
If I select a default image in the storyboard editor it will appear on the right side of the nav bar without any problems, but as soon as I select the hamburger button in the storyboard editor I get the same problem as before. I've tried with multiple different images and I've changed up the code a little bit with no success. Is there a way to resize the image I'm using so it will fit in the nav bar properly or is there just something wrong with my code?
Here is my code from viewController.swift below:
override func viewDidAppear(_ animated: Bool) {
let nav = self.navigationController?.navigationBar
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
imageView.contentMode = .scaleAspectFit
let titleImage = UIImage(named: "logowhitecircle")
imageView.image = titleImage
navigationItem.titleView = imageView
let menuButton = UIButton(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
menuButton.contentMode = .scaleAspectFit
let menuImage = UIImage(named: "hamburgericon")
menuButton.setImage(menuImage, for: .normal)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: menuButton)
You need to set image size in the image assets like 3x = 84px, 2x=56px, 1x = 28px,
see the apple document for more info: https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/custom-icons/
let menuButton = UIBarButtonItem(image: UIImage(named: "logowhitecircle"), style: .plain, target: self, action: #selector(menuButtonTapped(_:)))
self.navigationItem.rightBarButtonItem = menuBu
tton
Try Using below code:
let imageBurger = UIImage(named: "hamburgericon")!
let btnLeftMenu = UIButton(type: .system)
btnLeftMenu.bounds = CGRect(x: 10, y: 0, width: imageBurger.size.width, height: imageBurger.size.height)
btnLeftMenu.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
btnLeftMenu.setImage(imageBurger, for: UIControl.State())
btnLeftMenu.setTitle(title, for: .normal)
let leftButton = UIBarButtonItem(customView: btnLeftMenu)
self.navigationItem.leftBarButtonItem = leftButton
Try this module FFBadgedBarButtonItem it's easy to use module, here is the documenataion Link
Below is my code how to implement it!
let image = UIImage(named: "yourImage")
let finalImage = resizeImage(image: image!, newWidth: 30)
navigationItem.rightBarButtonItem = FFBadgedBarButtonItem(image: finalImage, target: self, action: #selector(rightButtonTouched))
And here is the calling function
#objc func rightButtonTouched() {
// what event you need to perfom by clicking on this button
}
You need to create Bridging Header to work with this Obj-C module.
: D
Try this:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//create a new button
let button: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
//set image for button
button.setImage(UIImage(named: "hamburgericon"), forState: UIControlState.Normal)
//add function for button
button.addTarget(self, action: "customButtonPressed", forControlEvents: UIControlEvents.TouchUpInside)
//set frame
button.frame = CGRectMake(0, 0, 40, 40)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barButton
}
//This method will call when you press button.
func customButtonPressed() {
println("button pressed")
}
}

how to set the image position and size of image that inserted in navigation bar?

actually I don't know the correct way how to make an image inside the navigation bar like this, either using navigation controller or by using custom view by myself
I need to insert these 2 image as bar button and image title
so I tried to use navigation controller and insert an image in viewDidLoad like the code below:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// insert image title
let aspectRatio : CGFloat = 0.25
let widthOfImageHeader = view.frame.width * 0.5
let heightOfImageHeader = widthOfImageHeader * aspectRatio
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: widthOfImageHeader, height: heightOfImageHeader))
imageView.contentMode = .scaleAspectFit
let image = UIImage(named: "testImage2")
imageView.image = image
navigationItem.titleView = imageView
// set bar button image
//create a new button
let button = UIButton(type: .custom)
//set image for button
button.setImage(UIImage(named: "hamburgerIcon"), for: .normal)
//set frame
button.frame = CGRect(x: 0, y: 0, width: 53, height: 51)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.leftBarButtonItem = barButton
}
}
but the result is like the image below:
the position of image title is not exactly in the center for iPhone 5s and bar button seems a little bit off in the right.
and if I assign the image right bar button, using
/
/create a left button
let button = UIButton(type: .custom)
//set image for button
button.setImage(UIImage(named: "hamburgerIcon"), for: .normal)
//set frame
button.frame = CGRect(x: 0, y: 0, width: 53, height: 51)
let barButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.leftBarButtonItem = barButton
//create a right button
let button2 = UIButton(type: .custom)
//set image for button
button2.setImage(UIImage(named: "backButton"), for: .normal)
//set frame
button2.frame = CGRect(x: 0, y: 0, width: 53, height: 51)
let barRightButton = UIBarButtonItem(customView: button)
//assign button to navigationbar
self.navigationItem.rightBarButtonItem = barRightButton
the result is even weirder
one of the button dissapears, the hamburger icon that should be on the left, now in the right
it will be far easier if I use custom view, but...is it weird if I use custom view that use like navigation bar? I am new in iOS Developer. Thanks in advance
Okay so here's what I usually do in a project with such kind of requirements (image at the navBar's title, and custom bar button items).
To answer first your question, you can actually do whatever you want.
Have indeed a custom view while having your viewController embedded inside a UINavigationController. But be sure to hide the navBar.
Have a visible navBar and viewContorller embedded in UINavigationController.
The ideal way for me is the latter.
The sample project below was made using my own old framework: https://github.com/glennposadas/gpkit-ios
You can copy any pieces of codes from that framework, modify/rename everything on it, and put in your production project.
If you want the result below, here's how I do it:
import GPKit
import UIKit
class ViewController: UIViewController {
// MARK: - Properties
internal lazy var button_Close: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "ham"), for: .normal)
button.imageEdgeInsets = UIEdgeInsets.init(top: 0, left: -30, bottom: 0, right: 0)
//button.addTarget(self, action: #selector(hamburger(_:)), for: .touchUpInside)
return button
}()
// MARK: - Functions
// MARK: Overrides
override func viewDidLoad() {
super.viewDidLoad()
GPLog(classSender: self, log: "viewDidLoad!")
// Title View Test: -
let navBarImage = UIImage(named: "ic_logo_navbar")!
self.setNavBarTitleWithFeedback(image: navBarImage, navBarTintColor: .white)
self.makeNavBarColor(color: UIColor.colorWithRGBHex(0x332F39), itemsTintColor: .white)
// Barbutton
let barButton = UIBarButtonItem(customView: self.button_Close)
self.button_Close.frame = CGRect(x: 0, y: 0, width: 55.0, height: 44.0)
let negativeSpacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.fixedSpace, target: nil, action: nil)
if #available(iOS 11.0, *) {
negativeSpacer.width = -30
}
self.navigationItem.leftBarButtonItems = [negativeSpacer, barButton]
}
}
extension ViewController: GPTitleViewDelegate {
func gpTitleView(userDidTapTitleView gpTitleView: GPTitleView) {
GPLog(classSender: self, log: "userDidTapTitleView🌈")
}
func gpTitleView(userDidFinishLongPress gpTitleView: GPTitleView) {
GPLog(classSender: self, log: "userDidFinishLongPress🌺")
}
}
Result:
I don't have your hex color, so it looks ugly.
I hope thish elps.

Custom bar button item not sizing properly

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.

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