Swift Small to Large Nav Bar Title Jumpy Transition - swift

So on my first vc I have set the nav bar to a large title. Then I have a button which goes to a vc with a nav bar with a small title.
When I go back from my second vc to the first, it displays the small title for a bit then jumps down to the large title.
Here is my code in the first vc bc its a tab view controller:
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.navigationBar.prefersLargeTitles = true
}
Here is the code for the second vc in the viewDidLoad():
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.font: UIFont(name: "Avenir-Black", size: 20)!]
self.navigationController?.navigationBar.prefersLargeTitles = false
This is what I mean about the jumpy transition
Thanks

On your second ViewController Try changing the NavBarPreference inside viewWillDisappear function.
Example:
func viewWillDisappear(_ animated: Bool){
self.navigationController?.navigationBar.prefersLargeTitles = true
}
So before going back to the first vc you change the NavBar preference first
Alternative Solution: Using Storyboard
You can click on the desired VC then click on its navBarItem then go to your right to properties and on Large Title Select Never, Always or Automatic from the dropdown list.
Example

Short answer is to not rely on largeTitleDisplayMode = .automatic (the default value) and prefersLargeTitles = true/false but instead to be explicitly setting .always or .never with prefersLargeTitles = true (yes even when using never).
You need to always have prefersLargeTitles to be true because of this from Apple doc:
If the prefersLargeTitles property of the navigation bar is false, this property has no effect and the navigation item’s title is always displayed as a small title.
This is an issue you have on iOS11/12 but on iOS13 it will be surfaced a bit differently.

Related

How to let search bar disappear immediately when moving to another VC

Below Gif is from my app, the 1st VC includes a search bar to filter the songs, and when press a row to transition to 2nd VC to show selected playing song.
The question here is that when 2nd VC is opened, the search bar is not disappeared immediately, it has like 1 or 2 seconds delay, could see that behavior from below GIF.
/ / / Here is my code, how could I solve this issue? Any hint is appreciate.
The search bar
var resultSearchController = UISearchController()
override func viewDidLoad() {
...
// add search bar
resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.hidesNavigationBarDuringPresentation = false
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
// set search Bar covered color, same with tableView's background color.
controller.searchBar.barTintColor = UIColor(rgb: 0x292f33)
self.tableView.tableHeaderView = controller.searchBar
return controller
})() // closure, learn it later!!
...
}
I set search bar to disabled state when leaving current VC.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
resultSearchController.isActive = false
}
/ / / Update, as matt's comment, I change the code to integrate search bar into navigation bar, and now the search bar is disappear immediately after opening VC2.
remove self.tableView.tableHeaderView = controller.searchBar and integrate the search bar into the nav bar navigationItem.searchController = resultSearchController. Now the behavior is same as Apple's inbox app.
searchController.searchBar.isHidden = false
Hiding the searchController instead of making the active state to false may solve your issue.
Try adding in the above line to your code in viewWillDisappear()
hopefully this helps.

How to get the navigation bar to show large title upon a segue back?

I have a tab bar app where one of the views is a UITableViewController containing static cells as content with 1 section and 1 row.
I want the Large Title to be set to "Always," so I made the selection on the storyboard and the title was large on the simulator. Now when the user taps "Start Chat," the app will segue to the Virtual Assistant View Controller, where the Large Title is set to "Never" on the storyboard. Now the problem is that when the user segues back to the previous view controller with the "Start Chat" table view cell, the title is not large anymore.
It is interesting that when I set the table view to be scrollable, the title becomes large again upon dragging down the table view. I made sure the navigation bar on the Navigation Controller storyboard is checked with the "Prefers Large Titles." I am using Xcode 11, and this was not a problem when using Xcode 10.
I tried creating a custom class for the view with the start chat button and this code did not work in making the title large from a segue back:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.prefersLargeTitles = true
What else could I do? Any help will be greatly appreciated!
I'd use willMove(toParent:) to change the title back before the segue is performed.
override func willMove(toParent parent: UIViewController?) {
navigationController?.navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.prefersLargeTitles = true
}
Set the properties when setting up the UINavigationController, before presenting it. If you already presented the navigation controller, try doing this to force-update the navigation bar:
navigationController?.navigationItem.prompt = ""
navigationController?.navigationItem.prompt = nil
I took this workaround from this question.
In your particular case, it would be better to subclass the navigation controller and set those properties in its viewDidLoad method, so its properties (largeTitleDisplayMode and prefersLargeTitles) are set in a self-contained code.

Navigation item views disappearing when using multiple search bars and interactive pop gesture

I'm using multiple UISearchBar's as titleViews in UINavigationControllers embedded in a UITabBarController. This all works just fine when I push and pop view controllers using the back button. But, the search bar starts to disappear when I pop using the interactive pop gesture.
I'm not sure how to fix this.
I've tried setting the titleView of the navigationItem in viewWillAppear and viewDidAppear but both didn't work.
The search bar accepts input and touches, it's just not visible.
Here's the viewWillAppear code:
override func viewWillAppear(_ animated: Bool) {
print("view will appear from base search")
super.viewWillAppear(animated)
print(self.searchController.searchBar)
self.definesPresentationContext = true
self.navigationItem.titleView = nil
self.navigationItem.titleView = self.searchController.searchBar
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
Here are some photos of what happens:
https://imgur.com/a/OQ7kb1q
The first photo is the homepage.
The second photo is a user typing in the search query.
The third photo is when a user returns after executing interactive pop gesture.
The fourth photo shows that you can still type in the search bar even though it's not visible.
The fifth photo shows you can still hit the cancel button next to the search bar even though that's not visible.
I fixed this by setting: self.navigationItem.searchController = searchController
instead of setting:
self.navigationItem.titleView = searchController.searchBar

small navigation title is showing for few seconds

I have set large title in viewWillAppear()
self.navigationItem.largeTitleDisplayMode = .always
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.title = "Reports"
But still when I redirect to next VC and come back I can see navigation Title in small size for a while and then I see large title, anybody know why and how to fix it?
If you want the next VC to have largeTitleDisplayMode false, you could try to set it in viewWillDisappear() of the current VC, like this:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.navigationBar.prefersLargeTitles = false
}
You should set this in the viewDidLoad of your view controller, not the viewWillAppear. It's the first part in the view lifecycle and where this work should be done

How can I fix my navigation bar back button?

Hi I've been trying to change my back button in my application's navigation bar. The problem is that I see the change when I load the view twice.
I've searched for the answer several times but I don't see what I really want. In fact, I'm new at this language so it's difficult.
What I tried is putting the following lines in the viewWillAppear method and others*:
nav?.navigationBar.backItem?.title = "Messages"
The result is that when I enter the view I see the back button's title as Back. Then if I press on that button and enter the view again the title changes as I want. On the other hand, what I want is to change the title when I load the view first.
*-> I've tried the same line in viewDidLoad too see if that does anything and in viewWillDisappear of the previous view, but nothing happens.
You are using method a change back button in your current ViewController it is wrong, because your navigationBar configured in past controller. If you use Storyboard, please will try this method in your parent controller:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let backItem = UIBarButtonItem()
backItem.title = "Messages"
navigationItem.backBarButtonItem = backItem
}
If you init newController in your parentController, you must to modify your a backButton in parentController, example:
// It's action for any button witch present your newController
#objc private func presentDetailViewContorller() {
let weatherDetailController = WeatherDetailController()
let navController = NavigationController(rootViewController: weatherDetailController)
let backItem = UIBarButtonItem()
backItem.title = "Messages"
navController.backBarButtonItem = backItem
self.present(navController, animated: true, completion: nil)
}
Good luck!