Navigation bar and tab bar turned black on iOS15 Xcode 13 - swift

Today I just updated my Xcode to version 13 and found that all the navigation bars and the tab bars of my project turned black, I didn't change any settings, my project was working fine on Xcode 12, and I have toggled it to light mode, I couldn't find a way to recover the appearances to the old ones.

Just simply check the "Translucent" in your attributes inspector.

Apply the following code to update the appearance of the navigation bar. This can be done in AppDelegate if you wish for it to be the appearance throughout the app.
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: .black]
appearance.backgroundColor = .white
// Default portrait view
UINavigationBar.appearance().standardAppearance = appearance
// There are other appearances you could apply it to as well...
// UINavigationBar.appearance().scrollEdgeAppearance = appearance
// UINavigationBar.appearance().compactAppearance = appearance

Make like this:
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .red
appearance.titleTextAttributes = [.font:
UIFont.boldSystemFont(ofSize: 20.0),
.foregroundColor: UIColor.white]
// Customizing our navigation bar
navigationController?.navigationBar.tintColor = .white
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
I wrote a new article talking about it.
https://medium.com/#eduardosanti/uinavigationbar-is-black-on-ios-15-44e7852ea6f7

Related

Swift Navigation Bar not change userInterfaceStyle on scoll

I have a problem when I try to change interface style (dark or light). If I set dark mode I get the navigation bar remains light when I scroll. If I set light mode the navigation bar becomes black. How can I solve this?
I use this code to change userInterfaceStyle:
window?.overrideUserInterfaceStyle = .dark
I found a solution by myself.
For everyone that has this problem the solution is:
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .systemBackground
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = UINavigationBar.appearance().standardAppearance
put this code inside TabBarController

How to set navbar and tabbar not transparent and their borders visible

I can not find any info in internet about this question. I have tableview in UIViewcontroller and it is embedded in navigation controller. I want that my navbar was always like in scrolling state (borders are visible) and same thing with tabbar. Here is photo what I have(1-st) and what I want (2-nd).
In AppDelegate file in didFinishLaunchingWithOptions method added:
//MARK: - NavBar appearance
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.backgroundColor = UIColor(named: "AccentColor")
UINavigationBar.appearance().standardAppearance = navBarAppearance
UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
//MARK: - TabBar appearance
let tabBarAppearance = UITabBarAppearance()
tabBarAppearance.backgroundColor = UIColor(named: "AccentColor")
UITabBar.appearance().standardAppearance = tabBarAppearance
UITabBar.appearance().scrollEdgeAppearance = tabBarAppearance

Xcode 13 - Navigation bar and status bar text color changing in swift OS 15

Recently I updated my Xcode to 13 and after that, I am facing some issues with the navigation bar and Status bar. I am using the tab bar in my view controller. After updating the Xcode, according to the version, I added some code related to the navigation bar.
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = UIColor(red: 58/255,green: 24/255, blue: 93/255, alpha: 1.0)
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
// Customizing our navigation bar
navigationController?.navigationBar.tintColor = .white
navigationController?.navigationBar.barTintColor = .white
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
}
Everything is working when I first opened the app. When I click on the other tab and then this tab. The status bar text color is changing.
I tried different ways to set the status bar text color. But nothing worked for me.
Use this function:
extension YourViewController {
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
If you just want to set to white colour you status bar in the entire project you can easily do it by adding the following keys into your project.plist file:
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
So, what does these keys do... You are just defining that you status bar colour will not be controlled by the any view controller and that the default colour will be "light theme" that is pretty much the white colour that you want in this case...
this would be the best approach if you do not intent to update the status bar colour all over the place.
this was tested and is working as expected on Xcode 13 and iOS [13.x,14.x,15.x]
If you want to update to customise or update the colours for the navigation bar you would should be able to do with an extension like this one bellow, just few examples but you guys should get what I mean:
extension UINavigationBar {
func clearBackground() {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithTransparentBackground()
navBarAppearance.shadowColor = UIColor.clear
navBarAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
self.standardAppearance = navBarAppearance
self.scrollEdgeAppearance = navBarAppearance
}
func blackColor() {
// Create an Appearance and customise as you wish.
// in this case just a black background with titles in white.
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithOpaqueBackground()
navBarAppearance.shadowColor = UIColor.black
navBarAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
self.standardAppearance = navBarAppearance
self.scrollEdgeAppearance = navBarAppearance
}
}
with this code you should be able to easy update on any view controller by just calling something like:
override func viewDidLoad() {
super.viewDidLoad()
// set the navigation bar color as transparent
self.navigationController?.navigationBar.clearBackground()
}

Swift: How to hide/move navigationTitle for small in-line navigation

I have a tableView that has a large navigation title of "My title". By default, when I scroll up, the large title turns into a small title. How do I go about hiding the small title during the small navigation bar but still show the large title when i scroll down? Is there a delegate i can use to notify me when navigation is transitioning for large title to small? Because my end result is to have my title be on the left bar bar button side when i scroll up.
Is there an easier to way move the title location to the left where left bar button would be?
My approach is create the left bar button with the same title as my navigation. I would hide it when my large navigation title is present then show it when large navigation title isnt. Meanwhile, I would hide the small navigation title when the small navigation bar is present. I hope this makes sense haha. Basically just trying to find a way to have my title on where the left bar button item should be.
Solution:
self.navigationItem.title = "hello"
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.titlePositionAdjustment = UIOffset(horizontal: -150, vertical: 0)
navBarAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
navBarAppearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
navigationController?.navigationBar.standardAppearance = navBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.title = "My Title"
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.titlePositionAdjustment = UIOffset(horizontal: -150, vertical: 0)
navBarAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
navBarAppearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
navigationController?.navigationBar.standardAppearance = navBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
navigationController?.navigationBar.prefersLargeTitles = true

Set UIImagePickerController navigation bar to opaque in iOS 13

I am presenting a UIImagePickerController to pick an image. My code is as simple as:
private lazy var imagePicker: UIImagePickerController = {
let picker = UIImagePickerController()
picker.navigationBar.isTranslucent = false
return picker
}()
func presentPicker() {
imagePicker.sourceType = .photoLibrary
imagePicker.modalPresentationStyle = .fullScreen
present(self.imagePicker, animated: true, completion: nil)
}
I am setting picker.navigationBar.isTranslucent = false to have an opaque navigation bar in the picker controller. Unfortunately this doesn't work on iOS 13 and the navigation & status bars are transparent.
Partial solution:
private func setOpaqueNavigationiOS13() {
UINavigationBar.appearance().backgroundColor = .white
}
private func resetNavigationiOS13() {
UINavigationBar.appearance().backgroundColor = .clear
}
I call the above functions to make the navigation bar opaque and to reset it when dismissing the picker. This makes the navigation bar opaque but the status bar is transparent. I can implement a hack to make the status bar opaque as well but I guess there should be a simpler solution.
EDIT:
I've also tried setting the navigation bar's appearance by the new UINavigationBarAppearance:
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .white
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().compactAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
}
Or:
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = .white
imagePicker.navigationBar.standardAppearance = appearance
imagePicker.navigationBar.compactAppearance = appearance
imagePicker.navigationBar.scrollEdgeAppearance = appearance
}
Anyone that came up with a fix? Thanks
I am posting my solution in case it's helpful for others.
Although matt's answer is totally correct, it applies when all of you nav bar setup is done through UINavigationBarAppearance. This did not help in my case because I've already done this in AppDelegate:
// Make navigation bar transparent throughout whole app
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
And as my app showcases a lot of nav bar styling and I needed a quick fix just to satisfy iOS 13 changes I just did this:
// Set nav bar to opaque
if #available(iOS 13.0, *) {
UINavigationBar.appearance().setBackgroundImage(nil, for: .default)
}
Just don't forget to bring it back to transparent if needed.
In iOS 13, the correct way to customize the look of a navigation bar is through the UIBarAppearance architecture (the navigation bar's standardAppearance and so forth). You can apply this directly to the navigation bar or use the UINavigationBar appearance proxy.