Customize UINavigationBar back button - ios

I am new to iOS development. I am creating an application with TableViewController. On that screen I added a navigation bar too. I want the title and sub title,want to customize back button. I use the following code to add the title and sub title.
func setTitle(title:String, subtitle:String) -> UIView {
let titleLabel = UILabel(frame: CGRectMake(0, 25, 0, 0))
....
let subtitleLabel = UILabel(frame: CGRectMake(0, 54, 0, 0))
....
let titleView = UIView(frame: CGRectMake(0, 0, max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), 95))
.....
return titleView
}
Above code working fine. Now I want to customize the back button. My origional design should the following screenshot
. But my output not simillar it is like the following screenshot .
I am also using the following code to change the back button style
navigationController!.navigationBar.barTintColor = UIColor(red: 224/255, green: 224/255, blue: 224/255, alpha: 1.0)
navigationController?.navigationBar.backIndicatorImage = UIImage(named: "back_button")
self.navigationController!.navigationBar.backItem!.title = "";
// self.navigationController!.navigationBar.backItem!
navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "back_button")
Why my back button is different. Please someone help me to find out the issue.

set the navigation bar button item tint colour to white or default... and check
may be it will solve your problem
if you are using story board then open storyboard - Then Click the view where you have set the navigation bar image - click on that image - open attribute inspector - set the tint colour and if you have set it programatically then
self.navigationBar.barStyle = UIBarStyle.Black
self.navigationBar.tintColor = UIColor.whiteColor()

Related

Height of Navigation Bar in swift 4

In swift 3, I was able to change the height of a custom navigation bar using constraints and simply setting the height. Now I cannot do that anymore. It doesn't actually change the height of the navigation bar in the storyboard. Even when I go to the size inspector, the height field is gray and I am not able to change it. What is the best practice if I am presenting a view modally and want to display a navigation bar? It doesn't display automatically since it is a modally segue.
I had a similar issue, so i started to research and i found a solution that works for me... I'm gonna show how i did it, but i have to say that i don't use storyboards, so it is all in code...
1) You have to create a class of type "UIView", and then put this code in it:
class ExtendedNavBarView: UIView {
override func willMove(toWindow newWindow: UIWindow?) {
super.willMove(toWindow: newWindow)
layer.shadowOffset = CGSize(width: 0, height: CGFloat(1) / UIScreen.main.scale)
layer.shadowRadius = 0
layer.shadowColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1).cgColor
layer.shadowOpacity = 0.25
}
2) Then, go to the class where you have your navigationController. In the viewDidLoad method, put this code:
navBar.shadowImage = #imageLiteral(resourceName: "TransparentPixel")
let extendedBar = ExtendedNavBarView()
extendedBar.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: 82) //The height value is gonna determinate the total height of the navbar
view.addSubview(extendedBar)
extendedBar.backgroundColor = UIColor(red: 249/255, green: 249/255, blue: 249/255, alpha: 1.0)
Basically is an extension view for the navigationBar, depending of the value you put in the height, the total navbar is gonna be more or less taller.
If you want to learn more about it, you can go here:
Custom NavigationBar
Also, the "TransparentPixel" image is in the page, you just have to download the sample project.

Changing the tint color is not changing the font of the "cancel" button inside the search bar

I have a UIView called SearchView, and I am adding the searchController.searchBar as a subview of the UIView.
Inside viewDidLoad(), I am changing the search bar in my UISearchController like so:
//makes background transparent
searchController.searchBar.backgroundImage = UIImage()
//makes magnifying glass white
let iconView:UIImageView = tf!.leftView as! UIImageView
iconView.image = iconView.image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
iconView.tintColor = UIColor.whiteColor()
//changes text color to white
let tf = searchController.searchBar.valueForKey("searchField") as? UITextField
let attributedString = NSAttributedString(string: "", attributes:[NSForegroundColorAttributeName : UIColor.whiteColor()])
tf!.attributedPlaceholder = attributedString
tf!.textColor = UIColor.whiteColor()
//changes search field background color
tf!.backgroundColor = UIColor(red: 82/255, green: 91/255, blue: 93/255, alpha: 1)
//HERE: should make the cancel button font white...
searchController.searchBar.tintColor = UIColor.whiteColor()
searchView.addSubview(searchController.searchBar)
And in the AppDelegate, I have
UIBarButtonItem.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).tintColor = UIColor.whiteColor()
In your app delegate at launch time, say this:
UIBarButtonItem.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).tintColor = UIColor.whiteColor()
Note that this will have an effect only when there is editing going on in the search bar. If there is no editing in the search bar, there is nothing to cancel, so the Cancel button is dimmed and has no color (it's a kind of grey based on the tint color).

NavigationBar title doesn't appear

I add NavigationBar programmatically and later added title to it, but it doesn't appear at all. What is the problem here?
let navigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 55))
navigationBar.barTintColor = UIColor(red: 44/255, green: 54/255, blue: 63/255, alpha: 1)
navigationController?.navigationItem.title = "AAA"
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.whiteColor()]
view.addSubview(navigationBar)
navigationBar appears, but title not. How to fix it?
I've tried this too:
navigationBar.topItem?.title = "BBB"
nothing again
Hope this will help you out.
// Create the navigation bar
let navigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 64))
// Offset by 20 pixels vertically to take the status bar into account
navigationBar.backgroundColor = UIColor.whiteColor()
// Create a navigation item with a title
let navigationItem = UINavigationItem()
navigationItem.title = "Title"
// Assign the navigation item to the navigation bar
navigationBar.items = [navigationItem]
// Make the navigation bar a subview of the current view controller
self.view.addSubview(navigationBar)
This code is working for me.
UPDATE : Swift 4/Swift 5
// Create the navigation bar
let navigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 64))
// Offset by 20 pixels vertically to take the status bar into account
navigationBar.backgroundColor = UIColor.white
// Create a navigation item with a title
let navigationItem = UINavigationItem()
navigationItem.title = "Title"
// Assign the navigation item to the navigation bar
navigationBar.items = [navigationItem]
// Make the navigation bar a subview of the current view controller
self.view.addSubview(navigationBar)
Navigation bar title is set in the view controller being displayed. Normally this is done in view did load on the view controller:
override func viewDidLoad() {
super.viewDidLoad()
self.title = "AAA"
}
EDIT: After realising that OP is adding UINavigationBar on to UIViewController and not using standard UINavigationController:
let navigationBar = UINavigationBar(frame: CGRectMake(0, 0, self.view.frame.size.width, 55))
navigationBar.barTintColor = UIColor(red: 44/255, green: 54/255, blue: 63/255, alpha: 1)
let navigationItem = UINavigationItem.init(title: "AAA")
navigationBar.items = [navigationItem]
view.addSubview(navigationBar)

Changing the Navigation Bar in Swift

I would simply like to know how to make my navigation bar look like the one on the left in the image below:
My app uses a navigation controller, and the navigation bar by default looks like the screen on the right in the image. I don't like it being so small and would like it higher and also to be able to change the colour and the font of the text used for the header.
I would appreciate any help in how to do this and where to place the code.
thanks
There are many ways to costumize your navigation bar:
//You can change the bar style
navigationController?.navigationBar.barStyle = UIBarStyle.Black
// You can change the background color
navigationController?.navigationBar.barTintColor = UIColor(red: 4 / 255, green: 47 / 255, blue: 66 / 255, alpha: 1)
// You can add a logo on it
let navBarImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
navBarImageView.contentMode = .ScaleAspectFit
let navBarImage = UIImage(named: "myNavBarLogo.png")
navBarImageView.image = navBarImage
navigationItem.titleView = navBarImageView
//You can change the text color
navigationController?.navigationBar.tintColor = UIColor.yellowColor()
//You can change the font
if let font = UIFont(name: "AppleSDGothicNeo-Thin", size: 34) {
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName: font]
}
You just need to play with those attributs to get the Navigation Bar as you want.
I hope that helps you!
You can change the navigation bar in Interface Builder.
You can change the background color by changing the bar tint. You can also change the title font, color, and etc., as you can see below:

iOS Custom Status Bar Background Color not displaying

I am trying to fill the status bar background color to orange using the following
UINavigationBar.appearance().tintColor = UIColor.orangeColor()
UINavigationBar.appearance().barTintColor = UIColor.orangeColor()
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
However, I get a white status bar that should be filled with orange instead from following this example: Customize navigation bar appearance with swift
I am setting this up in the AppDelegate.swift file under didFinishLaunchingWithOptions method to apply it to the entire app.
I have edited my info.plist to the following: View controller-based status bar appearance => NO
Does anyone know what I am doing wrong?
Edit: I'm not sure if it matters but the view is in a UITabBarController
Edit 2: This is happening in all the views actually, not just the UITabBarController.
Edit 3: Thanks #Utsav Parikh
I am adding a view now on top of the status bar and it for a brief moment while the app loads the status bar is orange but, once it finishes loading it gets pushed OFF the view and replaced with the generic white status bar.
Why would this be happening?
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.mainScreen().bounds.size.width, height: 20.0))
view.backgroundColor=UIColor.orangeColor()
self.window!.rootViewController!.view.addSubview(view)
Edit for Swift 3:
with UITabBarController
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = .orange
self.view.addSubview(view)
Without embedded controllers
I realize some people come here not only for the status bar, but actually the navigation bar, so I learned a few tricks along the way to do it without any embedded controllers:
Add this method in your AppDelegate.swift and call it in the didFinishLaunchingWithOptions
func customizeAppearance() {
UINavigationBar.appearance().barTintColor = UIColor.black
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
UITabBar.appearance().barTintColor = UIColor.black
let tintColor = UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0)
UITabBar.appearance().tintColor = tintColor
}
Edit for Swift 3:
With UITabBarController
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = .orange
self.view.addSubview(view)
Without embedded controllers
I realize some people come here not only for the status bar, but actually the navigation bar, so I learned a few tricks along the way to do it without any embedded controllers:
Add this method in your AppDelegate.swift and call it in the didFinishLaunchingWithOptions
func customizeAppearance() {
UINavigationBar.appearance().barTintColor = UIColor.black
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
UITabBar.appearance().barTintColor = UIColor.black
let tintColor = UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0)
UITabBar.appearance().tintColor = tintColor
}
Thanks to #Utsav I added the following subview to my UITabBarController and this seems to be working now:
let view = UIView(frame:
CGRect(x: 0.0, y: 0.0, width: UIScreen.mainScreen().bounds.size.width, height: 20.0)
)
view.backgroundColor = UIColor.orangeColor()
self.view.addSubview(view)
The UITabBarController doesn't seem to play well in AppDelegate. If anyone has a better way let me know but, as of now this is the solution I have come around to.
Add this code in didFinishLaunchingWithOptions in AppDelegate
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.mainScreen().bounds.size.width, height: 20.0))
view.backgroundColor=UIColor.orangeColor()
self.window.rootViewController.view.addSubview(view)
Hope it helps you....!!!
This is how I did it without adding a view in a VC with in a NavBarController
I wanted the color of the status bar to be the same as the VC view color so I just wrote:
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.grayColor()
self.navigationController?.navigationBar.clipsToBounds = true
}
Try it.
I think your last line is reverting your changes, try this:
override func viewWillAppear(animated: Bool) {
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
super.viewWillAppear(animated)
var nav = self.navigationController?.navigationBar
nav?.barStyle = UIBarStyle.Black
nav?.tintColor = UIColor.orangeColor()
nav?.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
}
After what u did in info.plist to the following: View controller-based status bar appearance => NO.
Add this code in AppDelegate.swift file under didFinishLaunchingWithOptions:
var navigationBarAppearace = UINavigationBar.appearance()
navigationBarAppearace.tintColor = uicolorFromHex(0xffffff)
navigationBarAppearace.barTintColor = uicolorFromHex(0x2E9AFE)
// change navigation item title color
navigationBarAppearace.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor()]
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
and u can select any hex code for ur choice of color..!! Enjoy..!!
Sorry, forgot to use hexcode you will be needing this also so add this code anywhere in your AppDelegate.swift:
func uicolorFromHex(rgbValue:UInt32)->UIColor {
let red = CGFloat((rgbValue & 0xFF0000) >> 16)/256.0
let green = CGFloat((rgbValue & 0xFF00) >> 8)/256.0
let blue = CGFloat(rgbValue & 0xFF)/256.0
return UIColor(red:red, green:green, blue:blue, alpha:1.0)
}
Simon's answer in swift 3
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = .orange
self.view.addSubview(view)
There is one other way I know which uses private api. This has some benefits when orientation changes and keyboard is presented and view move up. I've used it and was lucky every time (app was released in the app store).
func setStatusBarBackgroundColor(color: UIColor) {
guard let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else { return }
statusBar.backgroundColor = color
}
Swift 3:
In your AppDelegate.swift file paste the code bellow into your didFinishLaunchingWithOptions method:
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = UIColor(red: 255/255, green: 130/255, blue: 0/255, alpha: 1.0) // Organge colour in RGB
self.window?.rootViewController?.view.addSubview(view)
This works fine for me!
There is a main difference in tintColor and changing the background color of UINavigationBar. The best way in my opinion is apply a background image, made by 1 pixel square image of just one color.
Like that:
let tabbarAndNavBarBkg = UIImage(named: "nav_tab")
UINavigationBar.appearance().setBackgroundImage(tabbarAndNavBarBkg, forBarMetrics: .Default)
Or you can create a category on UIColor to return a UIImage given a UIColor instance, in objC:
+ (UIImage *) imageWithColor:(UIColor*) color {
CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return colorImage;
}
UINavigationBar.appereance() works for upcoming viewControllers, but not the currently displayed rootViewController. To achieve this I have added the following to my didFinishLaunchingWithOptions:
UINavigationBar.appearance().tintColor = myColor
let navigationController = UIApplication.sharedApplication().windows[0].rootViewController as! UINavigationController
navigationController.navigationBar.barTintColor = myColor
navigationController.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : myTextColor]
navigationController.navigationBar.translucent = false
navigationController.setNeedsStatusBarAppearanceUpdate()

Resources