UISearchController: UITableView section index overrides searchBar

I am creating an iOS 8 application that uses the new UISearchController. In the table view associated with the search controller, I use a section index so that users quickly switch from one section of the table to another. It works fine, but the partition index overlaps the search string on the table / search controller. Has anyone encountered this problem before, and if so, how did you solve it? The following shows how I initialize my search controller:

self.resultsTableController = [self.storyboard instantiateViewControllerWithIdentifier:[SelectSpecialtySearchResultsTVC storyboardId]]; UINavigationController *searchResultsNavController = [[UINavigationController alloc]initWithRootViewController:self.resultsTableController]; self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsNavController]; self.searchController.searchResultsUpdater = self; self.searchController.hidesNavigationBarDuringPresentation = NO; self.searchController.searchBar.barTintColor = [UIColor colorWithHexString:kColorGrayLight]; self.searchController.searchBar.translucent = NO; self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, [self.view bounds].size.width, 44.0); self.searchController.searchBar.delegate = self; self.tableView.tableHeaderView = self.searchController.searchBar; //present the search display controller within the confines of this class table view self.definesPresentationContext = YES; // we want to be the delegate for our filtered table so didSelectRowAtIndexPath is called for both tables self.resultsTableController.tableView.delegate = self; self.searchController.delegate = self; 

enter image description here

+7
ios uitableview uisearchbar uisearchcontroller
source share
5 answers

Finally, he came up with an acceptable solution to this issue. This answer is based on my question above (I use all the same code minus what has changed here). The main thing to note here is that @andrewbuilder was right - adding a search bar as a table title ensures that the search bar scrolls; it just acts like any other kind of table header.

What I ended up was a combination of things. The main change I made in my approach was to change the way my main controller represents my search controller. In particular, I switched from self.definesPresentationContext = YES; before self.definesPresentationContext = NO;

What this does is essentially present your search controller on top of your main screen, and not inside it. This creates a constructive compromise in that now you have to deal with the layout of 2 view controllers, and not just one. But I was fine with that.

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 this property to be equal to my searchBar and added it to my subspecies like this:

 self.searchBar = self.searchController.searchBar; [self.view addSubview:self.searchBar]; 

To make it look right, I had to make sure that my table position x is equal to the bottom of the search bar frame. You can do this in different ways: either in code, or in Interface Builder, or using a combination of both. I will leave you to figure out the right choice for myself.

Again, the trade-off is that you need to configure two view controllers and make it look like the same screen, even if it is not configured (setting up the navigation bar, handling segues, etc.). This seems like a necessary evil that my team and I were ready to accept. Hence, the following steps to create this work were useless with the edgesForExtendedLayout property on both view controllers (as well as contentInset in table views). I will not write this code here, as it will probably be different for everyone depending on their design. However, the essence of it.

Feel free to add to this thread if you find a simpler solution. I searched everywhere, but with UISearchController being a very new control, there is not much documentation / information (and its quirks).

+1
source share

just change the background color of the index section:

Swift:

  tableView.sectionIndexBackgroundColor = UIColor.clearColor() 
+8
source share

I had similar problems creating a table view that includes a search bar.

Try changing the appearance of the following properties ... this may help you find the right solution.

If you are using Interface Builder / Storyboard, in the Attribute Inspector set your search bar with the following properties:

  • Search Style = Minimum
  • Bar Style = Default
  • Transparent = YES
  • Bar Tint = Default

Storyboard Attribute Inspector

These properties can, of course, be set in code:

 self.searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal; self.searchController.searchBar.barStyle = UIBarStyleDefault; self.searchController.searchBar.translucent = NO; // By not setting the barTintColor property, it remains default // self.searchController.searchBar.barTintColor = [UIColor yourColor]; 

Then, in your table controller code, enter the following UITableView properties:

 // Prepare custom colours as needed UIColor *brightBlueColour = [UIColor colorWithRed:0.40 green:0.90 blue:1.00 alpha:1.00]; // Set section index properties for your table view [yourTableView setSectionIndexColor:[UIColor brownColor]]; [yourTableView setSectionIndexTrackingBackgroundColor:[UIColor brightBlueColor]]; if ([yourTableView respondsToSelector:@selector(sectionIndexBackgroundColor)]) [yourTableView setSectionIndexBackgroundColor:[UIColor clearColor]]; // Set additional properties for background colour CGRect frame = self.tableView.bounds; frame.origin.y = -frame.size.height; UIView *viewBackground = [[UIView alloc] initWithFrame:frame]; [viewBackground setBackgroundColor:self.brightBlueColour]; [yourTableView addSubview:viewBackground]; 

This combination provides a more acceptable look, in my opinion, and I use it in my applications that use table views with search strings.

+1
source share

I know this is an old question, but I have seen this happen a couple of times. Instead of the above solutions, it’s easier to respond to the new UIView with the original restrictions, and then iOS does not compress the width to accommodate the table index.

those. in viewDidLoad

 let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: searchController.searchBar.bounds.size.height)) headerView.addSubview(searchController.searchBar) tableView.tableHeaderView = headerView 
+1
source share

The dirtiest and easiest solution (works as you see fit), just create a second tableView. For example (Swift 3):

  tableView = UITableView(frame: CGRect.zero, style: .grouped) tableView.delegate = self tableView.dataSource = self tableView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tableView) let cnt1 = NSLayoutConstraint(item: tableView, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0) let cnt2 = NSLayoutConstraint(item: tableView, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0) let cnt3 = NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: tableView, attribute: .trailing, multiplier: 1, constant: 0) let cnt4 = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: tableView, attribute: .bottom, multiplier: 1, constant: -1) constraintTableViewBottom = cnt4 view.addConstraints([cnt1, cnt2, cnt3, cnt4]) let tableView2 = UITableView(frame: CGRect.zero, style: .grouped) tableView2.sectionIndexColor = .black tableView2.sectionIndexBackgroundColor = .clear tableView2.delegate = self tableView2.dataSource = self tableView2.translatesAutoresizingMaskIntoConstraints = false tableView2.backgroundColor = .clear view.addSubview(tableView2) let cnt5 = NSLayoutConstraint(item: tableView2, attribute: .height, relatedBy: .equal, toItem: view, attribute: .height, multiplier: 1, constant: 0) let cnt6 = NSLayoutConstraint(item: tableView2, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1, constant: 0) let cnt7 = NSLayoutConstraint(item: view, attribute: .trailing, relatedBy: .equal, toItem: tableView2, attribute: .trailing, multiplier: 1, constant: 0) let cnt8 = NSLayoutConstraint(item: tableView2, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: 13) tableView2.addConstraint(cnt8) view.addConstraints([cnt5, cnt6, cnt7]) 

and

 func sectionIndexTitles(for tableView: UITableView) -> [String]? { if tableView == self.tableView { return nil } if searchController.isActive && searchController.searchBar.text != "" { return filteredCells.keys.map { return sections[$0] } } return sections } func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int { self.tableView.scrollToRow(at: IndexPath(row: 0, section: index), at: .top, animated: true) return sections.index(of: title)! } final func numberOfSections(in tableView: UITableView) -> Int { if tableView != self.tableView { return 0 } return sections.count } 

and for example

 final func updateSearchResults(for searchController: UISearchController) { filterCells(searchText: searchController.searchBar.text!) tableView.reloadSectionIndexTitles() } 
0
source share

All Articles