set UINavigationBar color dependent on view controller - ios

I want to set the UINavigationBar color per view controller, not in the app delegate, as that would be done like this.
UINavigationBar.appearance().backgroundColor = UIColor.whiteColor()
UINavigationBar.appearance().translucent = false
I have looked around and just cant find how to do this.I tried doing it like this but it did not work:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()
self.navigationController?.navigationBar.tintColor = UIColor.blackColor()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
How do I set the color dependent on the view controller and not globally?

From my understanding, you will need to have code in each view controller to set the nav bar colour. Try adding this code to the viewDidLoad for each of your view controllers:
if let navController = self.navigationController {
navController.navigationBar.tintColor = self.view.tintColor
}
This will make the nav bar's tint colour whatever the view controller's tint colour is, but you can obviously change this to any colour you want.
The beauty of this is you can literally just copy paste this without having to change anything, so it is really easy to implement across multiple view controllers (as there are no specific references to the name of the view controller).
I hope this helps.

Related

Supplymentary header view not taking to status bar collection view

I make this screen with collection view with using supplementary HeaderView. I want to make this HeaderView to the status bar. I make clear color to status bar but it is not working. Please help me with it.
I think you need to make the next, delete this view and put this image in the back of the navigation bar, the next is putting navigation bar transparent and the tint color in white like this :
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = .clear
self.navigationController?.navigationBar.tintColor = UIColor.white
You could try to get the contents of the collection view started earlier.
collectionView.contentInset.top = -14
So, first of all in your info.plst tap "+" button and this line.
Than in your UIViewController add this method.
override var prefersStatusBarHidden: Bool {
return true
}
Status bar will be hidden only in this viewController.

Styling the navigation bar in UIDocumentPickerViewController

In my app, the primary theme has blue navigation bars with white bar button items and titles.
I set the values for colors like this in the App Delegate.
UINavigationBar.appearance().isTranslucent = false
UINavigationBar.appearance().tintColor = .white
UINavigationBar.appearance().barTintColor = AppColors.blue
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
But in some view controllers, I'm required to invert these styles (white navigation bars with blue buttons and titles).
So in those view controllers, I simply set the new values in the viewWillAppear method.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.tintColor = AppColors.blue
navigationController?.navigationBar.barTintColor = .white
navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: AppColors.blue]
}
From one of these view controllers, I have to show a UIDocumentPickerViewController to pick a document file.
let documentPickerViewController = UIDocumentPickerViewController(documentTypes: [String(kUTTypePDF)], in: .import)
documentPickerViewController.delegate = self
present(documentPickerViewController, animated: true)
The user can preview it as well. I use the QuickLook framework to do that.
The problem is these view controllers, UIDocumentPickerViewController and QLPreviewController don't conform to the new navigation bar color values I set in the viewWillAppear method.
Master view controller has the blue navigation bar but the detail view's navigation bar is all white. Including the bar button items. So the buttons are not visible. It seems the values I set in the viewWillAppear method has no effect here. I commented out the appearance values from the App Delegate and the buttons show up in the default colors.
Same with the QLPreviewController view controller.
I tried having the presenting view controller conform to UINavigationControllerDelegate but that didn't work.
I also tried getting a reference to the UIDocumentPickerViewController's navigation controller like this documentPickerViewController.navigationController but it returns nil as well.
How do I apply colors to the UIDocumentPickerViewController without changing the appearance values?
I uploaded a demo project here.

Tab Bar Color Slightly Changing with View BackgroundColor

Is there anyway to keep the tab bar color exactly the same regardless of the color of the view in the view controllers? The bottom picture with dashboard selected is darker than the top one because the view.backGroundcolor = .lightGray in the view controller.
I tried setting the view.bottomAnchor equal to the view.safeAreaLayoutGuide.bottomAnchor, but even then if the view is set as light gray, the tab bar will be slightly darker than the view controllers that have a white background.
I also set the self.tabBar.barTintColor = .white
and self.tabBar.alpha = 1.0
It's not just a perception thing either as I checked the exact color in hexcode.
Relevant lines of code :
final class TabBarViewController: UITabBarController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBar.barTintColor = .white
self.tabBar.alpha = 1.0
}
}
Should this code go in the init instead that sets up the corresponding view controllers?
The color you are setting for the tab bar is only a tint. The only way to get absolute control over the color is to make a resizable UIImage of the desired color and set the tab bar's backgroundImage property.
https://developer.apple.com/documentation/uikit/uitabbar/1623469-backgroundimage

How do I create a custom navigationController with image and name?

My goal is to create a UI that looks like this
The only way that I could think of is to embed a navigationController on the UIViewController then add UIView
Storyboard
Code - ProfileViewController
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationBarColor()
}
func navigationBarColor() {
navigationController?.navigationBar.backgroundColor = UIColor(red:0.91, green:0.04, blue:0.51, alpha:1.0)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
}
}
Result
Is my approach correct? or do I need to use a different method to achieve this result?
The best way to do this is to make the navigationBar invisible basically. Here is what I did to achieve the look you want:
Step 1:
Add the navigation controller and a view controller and hold control and drag from the navigation controller to the view controller and select root view controller(which i am pretty sure you have already done). Also, drag and drop a UIBarButtonItem onto the navigationBar in the view controller, not the navigationBar in the navigation controller.
Step 2:
Subclass the navigation controller and the view controller, in my example, mine are called CustomNavController.swift and MainVC.swift. In the storyboard, set them as the class of the controllers.
Step 3:
In the class you made for the view controller, set the code in the viewDidLoad to change the background color.
import Foundation
import UIKit
class MainVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 231/255, green: 11/255, blue: 129/255, alpha: 1)
}
}
And in the navigation controller class, add this code.
import UIKit
class CustomNavController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.isTranslucent = true
self.navigationBar.tintColor = .white
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
The Result:
Since you are using a navigation controller, you have to set the status bar style to lightContent in the navigation controller subclass like shown above. If you have other view controller that you want the status bar to be black in, you will have to implement the method preferredStatusBarStyle in the class and return .default unless, if the view controller has a navigation controller associated with it, the you would have to implement preferredStatusBarStyle in the navigation controller subclass like I showed in my example. If you have any questions feel free to leave a comment and I will answer when I can.
You can subclass navigation bar, but with that amount of size, i think it's not a good approach. What you are doing seems ok. It's a solution.
Your approach will work. To match your Sketch mockup as closely as possible, here are a few tips:
UINavigationBar's background color should be set using the barTintColor property. This will give the status bar the same background color.
Set the UINavigationBar's barStyle property to black. This will set the status bar's content color to white.
You might notice how the navigation bar's color is slightly different from the view you created beneath it. This is because UINavigationBar is translucent by default, so the background color has a reduced alpha value. You can set the UINavigationBar property isTranslucent to false to fix this.
An alternative approach (without UINavigationController) would involve creating a simple UIView to use as the status bar background, as shown here: https://stackoverflow.com/a/43264566/5223633.
First step, add this 3 lines of codes in your viewDidLoad methods of your controller class:
navigationController?.navigationBar.barTintColor = UIColor(red:0.91, green:0.04, blue:0.51, alpha:1.0)
navigationController?.navigationBar.tintColor = UIColor.white
UIApplication.shared.statusBarStyle = .lightContent
And then, select your info.plist file. When it's opened, add a row by right clicking on it. Give the key name:
View controller-based status bar appearance
and set it's value into:
NO
as boolean value.
see this info.plist screenshot example
Then run it.
You can create custom viewcontroller with Xib file after that load and add its view inside your navigation bar. Hide back button if required and update navigationBar height
accordingly
navigationItem.hidesBackButton = true
navigationController?.navigationBar.frame.size.height = 100
guard let yourCustomView = UINib(nibName: "yourCustomXib", bundle: nil).instantiate(withOwner: nil, options: nil).first as? YourCustomView else {
fatalError("Missing yourCustomXib")
}
navigationController?.navigationBar.addSubview(yourCustomView)

Customising the UITabBar.appearance in each View Controller [Swift]

I'm trying to set the tab bar to have a different background image on each view controller.
class CharacterVC: UIViewController {
var tabBarApparence = UITabBar.appearance()
override func viewDidLoad() {
super.viewDidLoad()
tabBarApparence.backgroundImage = UIImage(named: "BlueTB") //Loaded from Image Asset
}
This works fine and changes it to blue in that view, however when I go to the next view it stays the blue colour and doesn't change to the red colour which I programmed in with this code:
class AnonVC: UIViewController {
var tabBarApparence = UITabBar.appearance()
override func viewDidLoad() {
super.viewDidLoad()
tabBarApparence.backgroundImage = UIImage(named: "RedTabBar")
// addtional code here
}
I have an additional 2 view controllers, one should display the green version of the image and the other the purple version of the image.
Any suggestions which could fix this?
If you want to change appearance of TabBar in a view controller is very easy. You can this in function viewDidLoad or viewWillAppear. The code is the next:
// Set color of titles and icons in tabBar
self.tabBarController?.tabBar.tintColor = UIColor.redColor()
// Set color of background tabBar
self.tabBarController?.tabBar.barTintColor = UIColor.blueColor()
Replace code to viewWillAppear()
Better set backgroundImage to tabBar, not to UITabBar.appearance()

Resources