I'm trying to make bottom slider menu containing a table view controller and a search controller inside of table view header. At this point, I added table view controller as a child view controller. After search bar is focused dimming view triggers but it covers screen main bound. What I expect is that dimming view stays inside the child view controller boundaries. I could not understand the reason why dimming view always added screen main bounds ? I have a screen shot to demonstrate the issue I have.
Thanks for your help.
class ChildTableViewController: UITableViewController {
lazy var searchController: UISearchController = {
let temp = UISearchController(searchResultsController: resultSearchController)
temp.dimsBackgroundDuringPresentation = true
return temp
}()
private var resultSearchController = ResultSearchTableViewController(style: .plain)
override func viewDidLoad() {
super.viewDidLoad()
prepareViewController()
}
func prepareViewController() {
self.tableView = UITableView(frame: .zero, style: .plain)
self.tableView.separatorStyle = .singleLine
self.tableView.register(ChildTableViewCell.self, forCellReuseIdentifier: ChildTableViewCell.identifier)
self.tableView.tableHeaderView = searchController.searchBar
self.definesPresentationContext = true
}
}
Screen shot
Even if its content appears over a child view controller context, the search controller itself is a presented view controller and prevents interaction with any other interface. Thus it makes sense that if you ask for the dimming view, the dimming view covers everything other than the search controller interface. If you don't like that, set obscuresBackgroundDuringPresentation to false.
(You should not be using dimsBackgroundDuringPresentation. Use obscuresBackgroundDuringPresentation instead.)
Related
I've embed UISearchController into the navigationbar and my view controller has the table view. When I click on searchbar and keyboard appears tableview and searchbar does not animate smoothly. It seems like searchbar is overlaping navigationbar.
Here is the code,
Declare searchcontroller as a variable like,
var resultSearchController = UISearchController()
and defination in viewDidLoad is like,
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.obscuresBackgroundDuringPresentation = false;
self.navigationItem.searchController = controller
return controller
})()
Animation issue is like below gif(watch till end to see slow animation)
I want same duration for animation for tableview, navigation bar, and searchbar.
Any help will be appreciated.
Don't set UITableView top anchor to be pinned to safeArea but to superview.
Important extra note to the accepted answer:
If you use a UIViewController with subviews, including a UITableView, the UITableView has to be the first subview (i.e.: at index 0).
I am unable to touch the view or scroll the tableview on didpresentSearchcontroller or willpresentSearchcontroller method of iOS 11 SearchController as shown in screenshot. There is some kind of dimming or UISearchView which not allowing me to touch the view controller or scroll the tableview. I think it disables the view.
The greycolor view is not letting me touch the viewcontroller or tableview.
How can i interact with viewcontroller or scroll the tableview.
I want to show result on this view controller only .
// I dont want to show anotherview controller as result
searchController = UISearchController(searchResultsController: nil)
I got it.
Use
let searchController = UISearchcontroller()
func willPresentSearchController(_ searchController: UISearchController) {
searchController.dimsBackgroundDuringPresentation = false
}
Since iOS 12 it is:
searchController.obscuresBackgroundDuringPresentation = false
You should add it before the refresh search.
I'm having issues with iOS 11's large titles when using a Table View Controller.
I have set prefersLargeTitles to true in the viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
}
When running my app the title appears as if prefersLargeTitles is set to small, but if I then scroll down, the large title appears.
I have 2 UIViewControllers, and they both display the large title correctly, bar the UITableViewController.
I have tried different combinations of setting prefersLargeTitles to true in the code and within the storyboard, where you can set Large Title to Automatic, Always or Never.
I can only find one other question on Stack Overflow which refers to this exact issue, but none of the answers seem to solve it.
Has anyone else who has run into this issue been able to solve it?
After setting prefersLargeTitles, you can trigger the large titles to show by calling setContentOffset on your UITableView.
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
self.tableView.setContentOffset(CGPoint(x: 0, y: -1), animated: true)
}
Perhaps you are reloading the tableView prior to viewDidLoad? I observed the same behavior today. In my case, I had a didSet on a variable that was set before viewDidLoad that called tableView.reloadData.
I was able to fix this by adding a guard so the reloadData only happened when the variable wasn't previously nil, meaning the first time.
Here's my calling class for reference...
/// Master Controller in UISplitViewController
class MyMasterViewController: UIViewController {
private let controller = MyTableViewController()
override func viewDidLoad() {
super.viewDidLoad()
controller.instanceVariable = data
showDetailViewController(navigationController, sender: self)
}
...
private func reloadDetail() {
controller.instanceVariable = newData
}
}
And here's the fix - added the guard statement below...
/// Detail Controller in UISplitViewController
class MyTableViewController: UITableViewController {
var instanceVariable: MyData! {
didSet {
guard oldValue != nil else { return }
tableView.reloadData()
}
}
// UITableViewController Methods...
}
Hope this helps! If my example doesn't make sense, I'd suggest commenting out all references to tableView.reloadData and then only re-adding when sure they aren't getting called until after the tableView loads initially.
You need to enable large titles on the navigation controller. It is tricky to find, so please see the screenshot below.
If your table view controller seques on to other detail view controllers then you should set large title to Never in the storyboard for those other view controllers.
DO NOT MESS with prefersLargeTitles in code like this:
self.navigationController?.navigationBar.prefersLargeTitles = false
I have a view controller that displays some user-entered items. In that view controller, I configure an UISearchController and a separate view controller to display the search results:
private lazy var filteredItemsViewController: UITableViewController = {
let controller = UITableViewController(style: .plain)
controller.tableView.keyboardDismissMode = .onDrag
return controller
}()
private lazy var searchController: UISearchController = {
let controller = UISearchController(searchResultsController: self.filteredItemsViewController)
controller.searchResultsUpdater = self
return controller
}()
I have noticed that the table view for the initial data has the expected frame. However, the table view that displays the filtered results has some extra space above the initial cell. It seems to match the height of the status bar, but I can't figure out how to remove the extra space. I have tried setting the frame of the table view of the filtered results, but that did not solve it.
Here is a side-by-side comparison of the table views:
What am I missing that will allow me to remove the extra space above the initial cell in the table view that displays search results?
I have made a UITableView Controller with a UISearchBar as the Table's header.
I have then embedded this View Controller into a UINavigationController, as the root view controller.
Now, when I tap on the Search Bar, the SearchBar seems to disappears and displays a white screen. The keyboard appears, but there is no Search Bar.
The Table View can scroll, but the search bar has simply vanished.
When I implement this UITableViewController without the Navigation Controller, it works perfectly. But something about the Navigation Controller is borking everything up.
I've had the same issue that was sometimes happening, especially with table view of small number of rows (less than 50).
It appears the searchBar is removed from the view hierarchy, precisely from the container view that is a child of the UISearchControllerView.
I've found a workaround to manually add back the searchbar as a subview of the UISearchControllerView container child. This is implemented in the delegate function (from UISearchControllerDelegate) didPresentSearchController:
func didPresentSearchController(searchController: UISearchController) {
if searchController.searchBar.superview == nil {
for searchCtrlChildView in searchController.view.subviews {
if searchCtrlChildView.frame.origin == CGPoint(x: 0, y: 0) { //Discriminate if by chance there was more than one subview
searchCtrlChildView.addSubview(searchController.searchBar)
break
}
}
}
}
I've also filed a radar to Apple on this as it is not fixed in iOS 8.4
Check the way I had my searchBar it in viewDidLoad
I have my viewController embedded in NavigationController too
My code (hope it helps) :
class myTableViewController: UITableViewController,UISearchResultsUpdating,UISearchControllerDelegate,UISearchBarDelegate
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()