Search bar behavior inside Navigation Bar is inconsistent in iOS 13 - swift

I am trying to include search bar inside the navigation bar through navigation item of the view controller.
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.title = "Sticky Section Headers"
self.edgesForExtendedLayout = .all
self.extendedLayoutIncludesOpaqueBars = true
self.navigationItem.searchController = UISearchController()
setUpNavBarAppearance()
}
This view controller has a collection view and when user taps on a cell in the collection view, i am pushing the a new instance of same view controller(demo purposes) on to the navigation stack..
The behavior for the search controller has been inconsistent between the two view controllers. For the first/root view controller, the search bar shows up by default, but for the second view controller that is pushed on to the navigation controller, the search is hidden by default until user scrolls down.. I would like keep the search appearance behavior consistent across both the screens..
I am aware of the hidesSearchBarWhenScrolling setting to false would keep the search bar visible all the time, but i want to hide the search bar while user is scrolling.
Is there anyway to get the consistent behavior?
Here is the gist file, if you like to try the code:
https://gist.github.com/prasadpamidi/829e636d4697fda025bb0795ee81e355
Appreciate any help.

Related

Adding a prototype cell to a table view in storyboard makes navigation bar title small

I have a View Controller which segues from a previous controller that has large titles. The navigation bar in the navigation controller has the Prefers Large Titles checkbox checked.
I have added a Table View to this new view controller. Until then, the title remains large. However as soon as I add prototype cells to the table view, the navigation bar becomes small.
In code I added this:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
navigationController?.navigationBar.prefersLargeTitles = true
}
The problem is, when the view controller comes into view, the title appears small for a second and then immediately shifts to large title.
How can I fix it so that it appear large as I segue and avoid that size shift once the title becomes visible?
it is a feature: when the user scroll, the large Title will disappear and show small title on top.
your problem happend because in the xib file:
your layout is small title and its change to largeTitle when it pushed.
but the view doesn't know that.
to fix this you just need to call: view.layoutIfNeeded() in the viewDidLoad() method.
override func viewDidLoad() {
super.viewDidLoad()
title = "Large title"
view.layoutIfNeeded()
}

UISearchController is visible at view start in a CollectionView with a custom layout

Edit: I changed the custom layout to flow, no changes. So I think the problem is not the custom layout
In my view controller with an embedded navigation controller, I have a CollectionView with a custom layout. In this view controller, I have implemented a UISearchController:
// Add searchbar in navigation controller
let searchController = UISearchController(searchResultsController: nil)
searchController.extendedLayoutIncludesOpaqueBars = true
searchController.searchResultsUpdater = self
searchController.automaticallyShowsCancelButton = false
searchController.searchBar.placeholder = ""
navigationItem.searchController = searchController
This code works fine for ViewControllers with tables etc, but when I open my view with the CollectionView, the search bar is visible at the start of the view, when it should be only visible by scrolling down.
My constraints for top is at the superview.
I have tried to look at the custom layout code to identify the problem, but was not able to find it.
How can I hide the search bar at view start?

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.

Tab Bar Controller isHidden, but stays hidden

Im currently designing an app that utilizes a tab bar controller.
On the messages tab (instant messages), I want the tab bar to disappear whenever a user is having/viewing his/her conversation with another person. To do so I used this:self.tabBarController?.tabBar.isHidden = true
It disables the tabBar, but now the issue is that whenever I hit the back button to return to previous views (embedded in a navigation controller), the tab bar is still hidden. On the other views, I've set tabBar.isHidden = false, but that doesn't seem to fix it and now I can't access any of the other tabs.
My question is: How can I hide the tabBar on one view but keep it visible when I return to previous views?
In TabBar firstViewController
override func viewWillAppear(animated: Bool) {
// Enable TabBar
self.tabBarController?.tabBar.hidden = false
}
In SecondViewController (Pushed from firstViewController)
override func viewDidLoad() {
super.viewDidLoad()
// Disable TabBar
self.tabBarController?.tabBar.hidden = true
}

Hide navigation bar with table view

I'm trying to hide navigation bar when I scroll my table view. It seems that when I scroll inside table view this one can't detect the scrolling event.. when I scroll outside table view navigation bar get hidden...how can I resolve ?
You need to set the navigation controller hideBarsOnSwipe to true
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.hidesBarsOnSwipe = true
}