Swift: weird "snapping" search bar animation after cancel button selection using UISearchController? - ios

I have a weird issue, where upon searching SO, could not find anyone else experiencing this issue.
Basically I have a UITableView inside a UIViewController, which is embedded in a UINavigationController. I've set up a UISearchController above the UITableView with the appropriate UISearchResultsUpdating and UISearchBarDelegate functionality simply like so:
var sC = UISearchController(searchResultsController: nil)
...
sC.dimsBackgroundDuringPresentation = false
sC.searchBar.placeholder = "Searching..."
sC.searchBar.delegate = self
sC.searchResultsUpdater = self
table.tableHeaderView = sC.searchBar
The problem is that when the search bar is visible, and the Cancel button is initiated, the search bar will animate back in place, but right before it stops, it has this snapping animation.
This can be seen in the demo video link (animated gif doesn't clearly show the issue): Search Bar Issue
If it is not expected behavior, how can I fix this so that the animation of the search bar is much more fluid instead of this snapping animation?
Thanks!

Related

iOS 11 tableView with searchBar issue

Please help to determine the reason of such behavior (it's hard to describe by words, so I recorded the short video) https://youtu.be/E2ks0liFX4I
In short words:
Initially it's able to scroll content beneath navigation bar. If press search field - the search bar looks like detached from table view and goes too high and overlapped by status bar (look at increased space between grey border of search bar and first row in the table). After Cancel button pressed - the search bar jumps down and now can't be hided by scrolling.
I'm using UITableViewController.
Search bar initialization in viewDidLoad:
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
tableView.tableHeaderView = searchController.searchBar
And in StoryBoard:
tableView settings
Not sure what u want. I guess u want the search bar to hide when scrolling?
I set searchbar to the navigationItem, then set the hidesSearchBarWhenScrolling property.
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = true

Custom position for UISearchBar

I'm currently trying to implement UISearchController and its associated UISearchBar.
I aim to have a UISearchBar just above my UITableView which goes top as soon as it has the focus, like the picture below (screenshot from my old UI with UISearchDisplayController, now deprecated):
I already tried to set my UISearchBar as header of the UITableView, it works well but I have 2 issues :
The search bar logically scrolls with the table view content
When the search bar takes the focus, it remains at the same position
Here is the way I configured my UISearchBar:
func configureSearchController() { // Method called in the viewDidLoad()
searchController = UISearchController(searchResultsController: nil)
searchController!.searchResultsUpdater = self
searchController!.dimsBackgroundDuringPresentation = false
searchController!.searchBar.placeholder = "searchfood.searchbar.placeholder".localized
searchController!.searchBar.sizeToFit()
searchController!.hidesNavigationBarDuringPresentation = false
print(searchController!.searchBar.frame)
// Place the search bar view to the tableview headerview.
foodsTableView.tableHeaderView = searchController!.searchBar
// Search bar
searchController!.searchBar.searchBarStyle = .prominent
searchController!.searchBar.barTintColor = ColorLSDP.corail
searchController!.searchBar.tintColor = ColorLSDP.beige
}
So I tried to remove the following lines:
foodsTableView.tableHeaderView = searchController!.searchBar
But when I did this, I was not able to see the UISearchBar anymore.
After checking some other SO topics, I just spotted that my UISearchBar was maybe hidden below my UINavigationBar. So I tried to add the following lines in the viewDidLoad() method:
self.navigationController?.navigationBar.isTranslucent = false
self.edgesForExtendedLayout = []
It changed nothing.
Anyway, it did not solve my main issue which is having this search bar initially positioned like the screenshot above.
Is there a way to do this properly with the brand new UISearchController ?
Thanks a lot for your upcoming answers,
Regards,
Seb R.

Swift ios11 NavigationItem SearchBar won't hide completely

Having an issue with adding a search controller to a navigationItem in iOS11 / Swift 4.
Basically everything works as expected for the most part, pull down will reveal the search bar and searching works fine. However when trying to hide the search bar by scroll back up... the bar won't hide completely and remains as a thin strip (see below).
I have declared my search controller as follows:
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.scopeButtonTitles = ["All", "Samples"]
searchController.searchBar.delegate = self
navigationItem.searchController = searchController
Before (scroll down to reveal search bar):
After (scroll up to hide):
As discussed in this Apple forums thread.
When the value of this hidesSearchBarWhenScrolling is true, the search bar is visible only when the scroll position equals the top of your content view, that's in case you are using a UIViewController, which view property is a normal UIView (It is not a subclass of UIScrollView).
Instead, try to use UITableViewController or ScrollView, it should work as expected
In my case it was happening only when there was a small num of items in the table.
I came to a non-technical, but rather a logical solution to show the search bar only when there are >10 items in the list. There is no need to have search when you have only a few items anyway.
Try to add this
self.navigationItem.hidesSearchBarWhenScrolling = true

UISearchController with UIBarPositionTopAttached throws UISearchBar offscreen; impossible to have standard UISearchController with UITableView?

I'm trying to create a similar experience to the Contacts apps in iOS 8. The primary components of this are:
Keep the search bar fixed below the navigation bar
Have the search bar attach to the top of the view (standard functionality) when presenting.
This, however, is easier said than done. After a while of struggling with tableHeaderView (which didn't allow for interaction in front of the table view, and was complex with the viewDidLayoutSubviews positioning), I decided to embed a UITableView within a UIViewController, so I could add the UISearchBar as a subview. This worked pretty well, and allowed interaction with the search bar at all scroll positions, and the insets weren't hard to calculate.
But, the search bar gets cut off below the status bar, when activated. Seems like a straightforward issue—even if I didn't experience it with the exact same implementation in a UITableViewController. So, I tried making sure all my properties were set up for alignment, in every possible view controller.
self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = YES;
self.automaticallyAdjustsScrollViewInsets = NO;
I've tried every possible combination of these, in viewWillAppear as well as viewDidLoad, as well as translucent navigation bars and different starting frames for the table view and search bar. No luck. So, I tried to adjust the frames or constraints, perhaps using the topLayoutGuide or just 0. Unfortunately, adjusting the frame in any of the UISearchControllerDelegate methods didn't actually adjust its presented position, and adding constraints crashed immediately when the active animation begins (due to super.top not existing in the view hierarchy at the time; removing the constraints in willPresent did absolutely nothing).
After struggling for a bit longer, I tried implementing positionForBar as the UISearchBar's delegate:
- (UIBarPosition)positionForBar:(id <UIBarPositioning>)bar {
return UIBarPositionTopAttached;
}
This seemed to adjust the height, but the search bar flies off the top of the view. When activated, the search bar seems to appear directly above the visible area. This is even worse than it getting clipped behind or below the UIStatusBar. I also tried to just hide the status bar when the search controller becomes active, but conditionally implementing prefersStatusBarHidden didn't work at all (returning YES works great without UISearchController active, but when active it shows the status bar again or it gets shown beneath it). I assume this is because UISearchController refuses to obey any standards or rules, as is now painfully clear.
I've been trying to figure this out for a few days now, and I can't think of a solution besides reimplementing the UISearchController class/animation entirely. Please help!
For the behavior you described, this works great for me 😊
var resultSearchController = UISearchController()
And the following in your viewDidLoad function:
//Search Bar
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.searchBar.sizeToFit()
controller.dimsBackgroundDuringPresentation = false
self.tableView.tableHeaderView = controller.searchBar
self.definesPresentationContext = true
return controller
})()
What worked for me was to subclass UISearchController and override the prefersStatusBarHidden in the subclass.
Also make sure View Controller Based Status Bar Appearance is set to YES
And in your viewcontroller containing the tableview / search bar:
self.definesPresentationContext = YES;
I have the same problem. I add a UISearchController to UIViewController,not using tableView.header. And the UISearchBar.superview.frame.origin.y is -44. So you cannot see the searchBar.
Method 1: You can change the frame of UISearchBarWrapperView in the didPresentSearchController,the delegate of UISearchControllerDelegate。But you will see the animation of this process.
Method 2: like JBlake say. Set self.definesPresentationContext = YES; after the UISearchController is init. It works!
What i understood is if u need searchbar under navigationbar as u mentioned in #1 its very easy just set a boolean (Solution for #1) searchController.hidesNavigationBarDuringPresentation = true
Unfortunately i couldnt fix the searchbar-offscreen-issue while navigationbar is hidden.

IOS8 UISearchController display searchbar directly

I am trying to display a simple search screen for my iphone app using a UISearchController.
I used a UITableViewController and a UISearchController that I embedded inside a UINavigationController
This get me the following screen (state 1)
When user click on the search field I get the screen below (state 2):
The search bar display nicely at the top of the screen below the status bar.
What I want to do is to get state 2 straight away without going to state 1
I tried to add this code
presentViewController(searchController, animated: true, completion: nil)
but it either does not show the searchbar if animated is false or display it as I want but after an unnecessary transition that temporaryly shows the navigation bar
Ok I just found how to do it reading this answer UISearchController in a UIViewController
I just need to add the searchbar like this to get the desired effect
searchController.hidesNavigationBarDuringPresentation = false
// tableView.tableHeaderView = searchController.searchBar
navigationItem.titleView = searchController.searchBar

Resources