I have an app with multiple views and controllers but on just one of those views I would like to make the top navigation bar transparent with white text. I have the following code in the controller for said view:
override func viewDidLoad() {
super.viewDidLoad()
let bar:UINavigationBar! = self.navigationController?.navigationBar
bar.tintColor = UIColor.whiteColor()
bar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
bar.shadowImage = UIImage()
bar.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
}
When I open the app the top bar on the other views looks as expected and when I open this view the top bar looks like I want it to. But when I navigate from the this view to the others, the other views inherit the changes made by the above code to the top bar.
Is there a way to prevent this so that the navigation bar only changes for that particular view while leaving the rest intact?
Thanks in advance!
There is only one navigation bar for any particular navigation controller, so if you change it in one controller, it will be changed for all. The way to fix that is to change it back to whatever you want for the other controllers in viewWillDisappear (or viewDidDisappear). You might also need to move the code you show to view willAppear if you are coming back to this same instance when another controller gets popped.
Related
I'm trying to create a twitter app, emulating the real app, using the twitter API. On the timeline view, I have a regular navigation bar, and when a user taps a user profile, the profile view has a transparent bar so that the user's banner image can be displayed. I used the following code to make the navigation bar transparent in the user profile view:
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
The problem I'm having is when I return from the profile view, the timeline navigation bar has become messed up (screenshots below). I'm guessing this is because I changed some aspects of the navigation bar in the view controller for the profile view, and that carried over when I returned to the timeline view.
How can I reverse the navigation bar transparency to fix the wonky navigation bar? In the timeline view controller I've tried using the following code to try to reverse it, but it doesn't work.
self.navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.isTranslucent = false
Timeline view with regular navigation bar
Profile view with transparent navigation bar
Timeline view with wonky navigation bar after returning from profile view
A similar case happened to me too. Later, I noticed that I didn't change the attributes of the navigation item in the right life cycle metod. Make it non-transparent, in viewWillAppear in timeline view controller and make it transparent before leave from the timeline view controller, in viewWillDisappear.
Could it be related to that?
In your viewcontroller in which you are changing navigation bar do something like
override func viewWillAppear(_ animated: Bool) {
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
navigationController?.view.backgroundColor = .clear
super.viewWillAppear(animated)
}
override func viewWillDisappear(_ animated: Bool) {
navigationController?.navigationBar.isTranslucent = false
navigationController?.view.backgroundColor = .blue
super.viewWillDisappear(animated)
}
#Julian, I had the same issue as you. I had a master view with a red navigation bar and wanted the detail view navigation bar to be transparent. I managed to get that working, but encountered the same glitch when going back to the master view. The navigation bar stayed transparent for 1.5 seconds or so, and then went back to the original red color. I couldn't solve it with styling the navigation bar, but managed to fix it a different way. It's not a preferred solution, but it has cost me so many hours now, that I'm okay with it.
Alright, what I did, was create an ImageView, and aligned that under the navigation bar with auto-layout. The navigation bar was 44 pixels in height, so the ImageView got the y position -44. I gave the ImageView the red color of the navigation bar, so that when it was transparent for 1.5 seconds, the user actually saw the ImageView instead of the navigation bar color.
I hope this helps you too.
I have an odd situation where I cannot for the life of me get an app to start with the UINavigationBar set to transparent black. The app consists of a UINavigationController with a UIPageViewController as root. These are loaded from a storyboard when the app launches.
The app runs and the UINavigationBar shows up as opaque. As soon as I start dragging the UIPageViewController it triggers some sort of redraw and the UINavigationBar becomes transparent as desired.
I tried a few different ways of setting the UINavigationBar to transparent black, and none of them produced behavior any different than described:
I set these keys in Info.plist:
<key>UIStatusBarTintParameters</key>
<dict>
<key>UINavigationBar</key>
<dict>
<key>Style</key>
<string>UIBarStyleBlack</string>
<key>Translucent</key>
<true/>
</dict>
</dict>
I set the UINavigationBar appearance in the AppDelegate in didFinishLaunchingWithOptions:
UINavigationBar.appearance().tintColor = UIColor.black
UINavigationBar.appearance().isTranslucent = true
I subclassed UINavigationController and set NavigationBar properties in viewDidLoad():
navigationBar.barStyle = .black
navigationBar.isTranslucent = true
navigationBar.setNeedsDisplay()
I set the NavigationBar properties in viewDidLoad() of the UIPageViewController (the navigation controller's root view controller):
navigationController!.navigationBar.barStyle = .black
navigationController!.navigationBar.isTranslucent = true
navigationController!.navigationBar.setNeedsDisplay()
I also tried toggling the navigation bar on / off to trigger a refresh
navigationController!.isNavigationBarHidden = true
navigationController!.isNavigationBarHidden = false
For the sake of completion, I set the navigation bar properties in viewDidLoad() of the child view controller of the UIPageViewController.
In every single case I get the same behavior: opaque bar until I touch the screen and start a drag, at which point it switches to transparent.
What's odd is that setting other attributes of the navigation bar, such as titleTextAttributes, leftButtonItem, and rightButtonItem works just fine and the changes are reflected immediately.
I had a similar requirement with Swift3 an achieved it in this way:
In your view controller which contains PageViewController add the following code in viewDidLoad()
func makeNavigationTranslucent() -> Void {
self.navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = UIColor.clear
self.navigationController?.navigationBar.backgroundColor = UIColor.init(colorLiteralRed: 0.5, green: 0.5, blue: 0.5, alpha: 0.9)
}
Note : Change navigationBar.backgroundColor to the one which you want.
In your storyboard select your controller and under attribute inspector with simulated metrics heading set top bar to Navigation Translucent Bar. Refer below image :
This is kind of a hacky solution, but I managed to get it working by hiding the default navigation bar and adding a new one over it. In the page view controller viewDidLoad() function:
navigationController!.isNavigationBarHidden = true
let newNavBar = UINavigationBar()
newNavBar.barStyle = .black
newNavBar.isTranslucent = true
newNavBar.titleTextAttributes = [NSFontAttributeName: UIFont.mainFontThin(24),
NSForegroundColorAttributeName: UIColor.white]
// etc...
navigationController!.view.addSubview(newNavBar)
newNavBar.frame = CGRect(
x:0, y:0,
width:navigationController!.view.bounds.width,
height:navigationController!.navigationBar.frame.height + UIApplication.shared.statusBarFrame.height
)
newNavBar.pushItem(navigationItem, animated: false)
This shows the translucent navigation bar like we want, but there's still a small problem where the app status bar is black under the translucent nav bar. As before, once you drag a finger the status bar updates to transparent. I'm not sure how to fix this, adding a call to setNeedsStatusBarUpdate() didn't help. So this is a partial fix.
I want to make my tabbar half transparent by setting the translucent value to true. However it is not doing the trick. I have a TabBarVC assigned to the tab bar with the following code. The tab bar remains solid
class TabBarVC: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
// color of background -> This works
self.tabBar.barTintColor = UIColor.purpleColor()
// color when selected -> This works
self.tabBar.tintColor = UIColor.redColor()
// This does not work
self.tabBar.translucent = true
}
I also tried to do something like
UIColor(red: 246.0/255, green: 246.0/255, blue: 246.0/255, alpha: 0.5)
But it does not seem to work. I did a bit of search on Google but everyones issue seems to differ from mine. Could anyone help me out here?
Thanks,
What you're doing is most likely working to adjust the transparency of the tab bar. However, you need to set the corresponding view controllers to be "Under Bottom Bar" in the IB.
I am trying to change the color of my navigation bar in a view which contains a UISearchController. I have previously set the color of my navigation bars for the whole app in my appDelegate, but i want this views nav bar to have a different color. The issue is that i dont know which function to place the code such that it will override the appDelegate code. For example, viewDidLoad and viewWilAppear do not change the color when the view first loads, only after i enter and cancel the searchController. Which function should i place the following?
UINavigationBar.appearance().backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
There are two ways to do this. You can either modify the appearance proxy that you have set up in the AppDelegate for the whole app, or you can modify the individual navigationbar for the particular screen.
When you dismiss the view - you need to reset the barTintColor in the viewWillDisappear.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// Set to new colour for whole app
UINavigationBar.appearance().barTintColor = UIColor.blueColor()
// Or, Set to new colour for just this navigation bar
self.navigationController?.navigationBar.barTintColor = UIColor.blueColor()
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
//Revert to old colour, whole app
UINavigationBar.appearance().barTintColor = UIColor.redColor()
//Revert to old colour, just this navigation bar
self.navigationController?.navigationBar.barTintColor = UIColor.redColor()
}
Instead of changing the navigation bars color directly, you should change the navigation controller's bar color in viewWillAppear and change it back when you dismiss the view.
How can I hide only the navigation bar and not the status bar, in the same way that Facebook does. Using navigationController.hidesBarsOnSwipe = true hides both. And so does navigationController?.setNavigationBarHidden(true, animated: true)
I have a table view, and when the table is scrolled I would like the navigation bar to hide to leave more room for the table
Popping this in the app delegate didFinishLaunchingWithOptions got me the same result. Then I just set hidesNavigationBarsOnSwipe to true in storyboard or in viewWillAppear
var view: UIView = UIView(frame:CGRectMake(0, 0,self.window!.rootViewController!.view.bounds.width, 20))
view.backgroundColor=UIColor(red: 32/255, green: 159/255, blue: 207/255, alpha: 1)
self.window?.rootViewController?.view.addSubview(view)