Swift 3: How to reverse a transparent Navigation Bar? - ios

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.

Related

Part over navigation bar has different background color

I am really struggling figuring out why there's a part on top of the navigation bar that has a different color than the navigation bar.
I have set the navigation like this:
navigationController?.navigationBar.tintColor = .white
navigationController?.navigationBar.backgroundColor = .primaryBlack
navigationController?.setNavigationBarHidden(false, animated: true)
And for some reason only one part is with that color but not everything. In some other parts that part is completely transparent making it look really odd.
I encountered this issue when ever my navigation bar is using large titles and push a view controller onto the navigation stack of the navigation controller, this gap seems to be at the top:
There seems to be some gap created for some reason and the large title navigation bar starts under the status bar.
The reason I understand as per the documentation is that the base view goes under the UINavigationBar and when this view is scrolled, the UINavigationBar needs to transform.
When a navigation controller contains a navigation bar and a scroll
view, part of the scroll view’s content appears underneath the
navigation bar. If the edge of the scrolled content reaches that bar,
UIKit applies the appearance settings in this property.
Simplest thing I do is to make the underlying view the same color as the navigation bar background in the view controller and keep the result of your code the same:
// Same as your code, only changed background to blue
navigationController?.navigationBar.tintColor = .white
navigationController?.navigationBar.backgroundColor = .blue
navigationController?.setNavigationBarHidden(false, animated: true)
// What I added
view.backgroundColor = .blue
This gives me:
Update using UINavigationBarAppearance
Can you try updating using UINavigationBarAppearance
// From your code, not sure of it's purpose
navigationController?.setNavigationBarHidden(false, animated: true)
let appearance = UINavigationBarAppearance()
// Color of the nav bar background
appearance.backgroundColor = .black // primary black for you
// Color for the titles
appearance.largeTitleTextAttributes
= [NSAttributedString.Key.foregroundColor : UIColor.white]
appearance.titleTextAttributes
= [NSAttributedString.Key.foregroundColor : UIColor.white]
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
// Color for the back button
navigationController?.navigationBar.tintColor = .white
Result:

Setting navigationBar to clear

I'm trying to set the Navigation Controller Navigation Bar to clear / opacity 0
I seem to have it somewhat working, when I run my code in the simulator the white background bar is there however if I navigate to my other page then back it disappears.
My code is the same as the answer in this question, yes but my issue is that the Nav Colour only works once I've navigated away from the first screen and gone back to it. It's not that it doesn't work completely.
import UIKit
class LoginMenuViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
}
}

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.

UINavigationBar transparent + on top of UITableView

I have a transparent UINavigationBar. I also set hidesBarsOnSwipe to true. I want my navigationBar be on top of the content and hides when scrolling. Basically i want to achieve this effect (Navigation Bar on top of the content and also hiddes when scroll):
For now i just have this code and works everything, but i'm not able to put the content of the view behind the navigationBar:
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.backgroundColor = .clear
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.hidesBarsOnSwipe = true
Here is a sample project , as you see the tableView is at the bottom of the navigationBar and just goes to the top when it hides the navigationBar.
On your view controller in Interface Builder disable Adjust Scroll View Insets. You can probably do it from code if you want as well.

Resources