UISearchController persisting after segue
You can hide the searchController manually by setting the active property to false in prepareForSegue
. Add the below code in prepareForSegue()
searchController.active = false
Alternatively, you should add the following line in viewDidLoad()
to get the default behaviour
definesPresentationContext = true
From the documentation for definesPresentationContext
A Boolean value that indicates whether this view controller's view is covered when the view controller or one of its descendants presents a view controller.
Discussion
When a view controller is presented, iOS starts with the presenting view controller and asks it if it wants to provide the presentation
context. If the presenting view controller does not provide a context,
then iOS asks the presenting view controller's parent view
controller. iOS searches up through the view controller hierarchy
until a view controller provides a presentation context. If no view
controller offers to provide a context, the window's root view
controller provides the presentation context.If a view controller returns true, then it provides a presentation
context. The portion of the window covered by the view controller's
view determines the size of the presented view controller's view.
The default value for this property is false.
Important note (from @paulvs in the comments)
Little gotcha. Set definesPresentationContext on the view controller, not the search controller, I think this is worth emphasising.
UISearchBar doesn't dismiss on push segue
Manual stop UISearchController
in prepareForSegue
searchController.active = false
Or add this in viewDidLoad
searchController.definesPresentationContext = true
UISearchController doesn't hide view when pushed
Put this in your caller's viewDidLoad:
Swift:
self.definesPresentationContext = true
Objective-C:
self.definesPresentationContext = YES;
This solved the problem for me.
UISearchController not properly dismissing when going out of scope
you should add the following line in viewDidLoad()
definesPresentationContext = true
See the documentation for details: definesPresentationContext
Using UISearchController with UINavigationController
Add this line in viewDidLoad()
definesPresentationContext = true
From the documentation for definesPresentationContext
A Boolean value that indicates whether this view controller's view is covered when the view controller or one of its descendants presents a view controller.
Discussion
When a view controller is presented, iOS starts with the presenting view controller and asks it if it wants to provide the presentation
context. If the presenting view controller does not provide a context,
then iOS asks the presenting view controller's parent view
controller. iOS searches up through the view controller hierarchy
until a view controller provides a presentation context. If no view
controller offers to provide a context, the window's root view
controller provides the presentation context.If a view controller returns true, then it provides a presentation
context. The portion of the window covered by the view controller's
view determines the size of the presented view controller's view.
The default value for this property is false.
UISearchController in-accessible
That's because underlying UITransitionView
sets incorrect value for accessibilityViewIsModalSelector
which traps VO within search view, which in your case is empty.
I can only think of patching this behavior by swizzling accessibilityViewIsModal
on private UITransitionView
.
I described the technique in a blog post I wrote:
http://www.morphineapps.com/blog/accessibility-on-ios
Relevant gists:
https://gist.github.com/pronebird/0d3c06485de50e100d1e93bcde08c94c#file-snippet-m
https://gist.github.com/pronebird/66aa70b005ed9af8d357cdc7e940542b#file-search-controller-snippet-m
UISearchController: Section Index of UITableView overlaps searchBar
Finally came up with an acceptable solution to this question. This answer builds off of my question above (I'm using all the same code minus what is changed here). The main thing to note here is that @andrewbuilder was right - adding the search bar as a table header view will guarantee that the search bar will move on scroll; it's just acting like any other table header view.
What I ended up doing was a combination of things. The main change I made in my approach was changing the way my main controller presents my search controller. Specifically, I went from self.definesPresentationContext = YES;
to self.definesPresentationContext = NO;
What this does is essentially presents your search controller on top of your main screen rather than within it. This creates a design trade-off in the fact that you now have to deal with the layout of 2 view controllers rather than just one. But that was something I was ok with.
The next thing I did was create a strong pointer to a UISearchBar
in my main view controller, which I called searchBar
. Then, I set that property to be equal to my search controller's searchBar and added it to my subview like so:
self.searchBar = self.searchController.searchBar;
[self.view addSubview:self.searchBar];
In order to get this to look right, I had to make sure my table's x position was equal to the bottom of the search bar's frame. You can do that in many ways: either in code, in Interface Builder, or with a combination of both. I'll leave you to figure out the right choice for yourself.
Again, the tradeoff here is that you have to set up two view controllers and make it look like it's the same screen even though it's not (customizing the nav bar, handling segues, etc). This seems to be a necessary evil that me and my team were willing to accept. From here, the next steps in getting this all working was messing with the edgesForExtendedLayout
property on both view controllers (as well as the contentInset
of the table views). I'm not going to write that code here since it will probably be different for everyone depending on their design. However, that's the gist of it.
Please feel free to add to this thread if you find a simpler solution. I searched far and wide, but with UISearchController
being a very new control, there's not a lot of documentation / info on it (and its quirks).
Related Topics
Exc_Bad_Access Automatic Handling
Get Name of Airplay Device Using Avplayer
Ios: Is Core Graphics Implemented on Top of Opengl
Ios11 Arkit: Can Arkit Also Capture the Texture of the User's Face
The Sandbox Is Not in Sync with the Podfile.Lock-Ios
Ios13 Share Sheet: How to Set Preview Thumbnail When Sharing Uiimage
Get Country Code from Country Name in iOS
How to Use Dark Mode in Simulator iOS 13
What Values Should I Use for Cfbundleversion and Cfbundleshortversionstring
Xcode 10B5 - Duplicate Symbol Linker Error, Can't Compile with Crashlytics
How to Render View into Image Faster
How to Show the Loading Indicator in the Top Status Bar
How to Tell What Profile/Signing Certificate Was Used to Sign .Ipa
How to Hide the Keyboard When I Press Return Key in a Uitextfield