Swift 4 : Navigation Bar looks different for the next page - ios

I just removed the navigation bar shadow line with the following code :
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
When I use this code and I try to open another page which belongs to the same navigation controller, its navigation bar looks different. I'm trying to set the same navigation bar background color and tint color, but it doesn't work. However, when I remove these codes, all the pages that I use work normally. How can I fix this issue?
Screenshots :

It's common behaviour. When you set backgroundImage then it's not possible to set new colour. You need to set setBackgroundImage to nil and then set new colour that you want inside next ViewController.
This library can help you to do it easily https://github.com/MoZhouqi/KMNavigationBarTransition
PS: See an example by the link
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
configureAppearance()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
configureAppearance()
}
func configureAppearance() {
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
}
}
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
configureAppearance()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
configureAppearance()
}
func configureAppearance() {
self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
self.navigationController?.navigationBar.barTintColor = UIColor.yellow
}
}

It looks like your navigation bar is translucent but your view controller doesn't extend behind it so you need the window which defaults to black.
Either
Check the box to extend the VC under top bars in interface builder
Change UIApplication.shared.keyWindow?.backgroundColor to .white
Make your nav bar opaque

Related

Set navigation bar separator color for screen transition in Swift (iOS 13/14)?

I have 2 screens with a common navigation controller and common navigation bar. The first screen should have no separator, the second one should have a separator of a custom color.
Code I tried:
1)
navigationController?.navigationBar.shadowImage = ...//some image with an appropriate color
let appearance = UINavigationBarAppearance()
appearance.shadowImage = navBarSeparatorColor.as1ptImage()
navigationController?.navigationBar.scrollEdgeAppearance = appearance
It seems the first chunk of code works for ios 12 and that is all. Nothing works for iOS 13 or 14.
Note: there are some similar questions but their "solutions" don't work for iOS 13 and there are no questions for iOS 14 at all.
I think on iOS 13, you need to set the appearance object inside navigationBar, for example:
class FirstViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.standardAppearance.shadowColor = .clear
}
}
class SecondViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.standardAppearance.shadowColor = .red
}
}
Please note there are other appearances: compactAppearance and scrollEdgeAppearance. Instead of shadowColor, you can also set shadowImage as well.

How to add view on top of navigation bar

How to add view above navigation bar?
I have a custom navigation controller and I want to present a view above nav bar (like on the screen), so it should be visible on other ViewControllers
Would be great if the solution will be on storyboard.
Tried to add on UIWindow did't help.
Swift 4.2, Xcode 10+
Okay, from what I can tell (via your comment reply, though it still isn't 100% clear), the best solution to your question would be to make the navigation bar transparent, such that you can see any navigationController-presented view controllers underneath it. For this, I'd suggest the following extension to UIViewController:
extension UIViewController {
func setupTransparentNavigationBarWithBlackText() {
setupTransparentNavigationBar()
//Status bar text and back(item) tint to black
self.navigationController?.navigationBar.barStyle = .default
self.navigationController?.navigationBar.tintColor = .black
}
func setupTransparentNavigationBarWithWhiteText() {
setupTransparentNavigationBar()
//Status bar text and back(item) tint to white
self.navigationController?.navigationBar.barStyle = .blackTranslucent
self.navigationController?.navigationBar.tintColor = .white
}
func setupTransparentNavigationBar() {
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.backgroundColor = .clear
self.navigationController?.navigationBar.isTranslucent = true
}
}
Using either of the first two methods in viewWillAppear of your UIViewController subclasses will let you make the navigation bar completely transparent with the statusBar text + wifi/battery indicators black or white as desired. From this, you can then display anything under the navigation bar by pinning your constraints to view.bounds.topAnchor. E.g. for a transparent navigation controller with white statusBar text:
class YourViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
setupTransparentNavigationBarWithWhiteText()
}
}

How to remove navigation bar colour clear in swift4?

I want to clear color of navigation bar. In my ViewController there is a background image on that, when i remove color of navigation barTintColor, navigationController.view.background and navigation background image then simulator shows me :-
I have been trying alots of codes but there is no solution found.
I want navigation Bar like that:-
with clear navigation bar color.
Is there any solution, let me know?
Thanks!
You can make the navigation bar transparent in viewWillAppear and remove transparency in viewWillDisappear as follows
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.isTranslucent = false
}
The background image and the back button will be visible
Better you must avoid the navigation bar. Hide the navigation bar in the navigation controller and user custom view in your view controller to avoid this issue.
Swift 5:: Calling below in AppDelegate's didFinishLaunchingWithOptions function does the trick (This will be applied to your all navigationBars though, don't forget to switch your view controllers)
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithTransparentBackground()
navigationController?.navigationBar.standardAppearance = navBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance

is it possible to change colour of only one view controller's navigation bar?

I tried changing the colour of navigation bar in one controller but it changes colour of navigation bar in every controller.
Don't use segue type as push/ show.
You can try present type. This will help you.
Here you will create a new navigationController. So, you can customise it for single viewController.
I hope it help full for you.
on your view controller apply below methods:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated: animated)
self.navigationController?.navigationBar.barTintColor = UIColor.red //current new color
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated: animated)
self.navigationController?.navigationBar.barTintColor = UIColor.white //other vc's color
}

Transparent navigation bar glitch

I need to make the navigation bar in some view controllers transparent (but with the bar buttons visible).
I wrote the following extension for that.
extension UINavigationBar {
func setTransparent(_ flag: Bool) {
if flag == true {
setBackgroundImage(UIImage(), for: .default)
shadowImage = UIImage()
backgroundColor = .clear
isTranslucent = true
} else {
setBackgroundImage(nil, for: .default)
}
}
}
The default styles for my navigation bars are as follows.
UINavigationBar.appearance().isTranslucent = false
UINavigationBar.appearance().tintColor = .white
UINavigationBar.appearance().barTintColor = UIColor(red: 45/255, green: 93/255, blue: 131/255, alpha: 1)
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
All this works fine. But there's a problem if I have to turn off the transparent effect.
Say in the first view controller I don't need the navigation bar to be transparent.
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.setTransparent(false)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.isTranslucent = false
}
}
I push to the second view controller from here. In here, the navigation bar is transparent.
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.setTransparent(true)
}
}
Now when I pop back to the previous view controller, I have to explicitly set the isTranslucent property to false. I do that in the viewWillAppear as you can see in the first code snippet.
But the problem is, the navigation bar is black for a second when it happens.
I want this to be smooth. How do I avoid this?
Demo project uploaded here.
I tried the solution described here to a similar question. But it doesn't completely fix my issue. The black bar is gone but the navigation bar doesn't appear for a second just like before as you can see here.
Black navigation bar you see is actually a navigation controller view background color. Try add this code in first view controller viewDidLoad method
navigationController?.view.backgroundColor = navigationController?.navigationBar.barTintColor
Setting the navigation controller view background color did fix the black issue for me, but I was still having the "delay" problem when popping a view controller.
I fixed it by changing the theme of my NavigationController on the willMove method of the view controller being popped. Something like this:
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
guard parent == nil,
let navController = self.navigationController else {
return
}
navController.navigationBar.isTranslucent = false
navController.view.backgroundColor = backgroundColor
navController.navigationBar.barTintColor = barColor
navController.navigationBar.tintColor = tintColor
}
Before Push I use
if let navigator = self.navigationController {
navigator.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigator.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.black]
navigator.pushViewController(viewController, animated: true)
}
this make the glitch disappear working fine...
note in my case background color was white

Resources