4
votes

Seems like a common iOS bug but I've tried every solution I can find and have seen no results.

I am creating a UISearchController and adding it to a UIView wrapper like this:

self.searchController = [[SearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.searchBar.delegate = self;

[self.searchBarWrapper addSubview:self.searchController.searchBar];
[self.searchController.searchBar sizeToFit];

The problem is that whenever the search bar is touched, the keyboard pops up, but the whole search bar disappears.

I looked at these posts:

and tried every solution, ultimately adding this initialization code:

self.searchController.hidesNavigationBarDuringPresentation = NO;
self.definesPresentationContext = NO;
self.navigationController.definesPresentationContext = YES;
self.navigationController.extendedLayoutIncludesOpaqueBars = YES;
self.extendedLayoutIncludesOpaqueBars = YES;

and these delegate functions

- (void)willPresentSearchController:(UISearchController *)searchController {
  // definitely runs, if I put a breakpoint here it stops
  self.navigationController.navigationBar.translucent = YES;
  [self.searchBarWrapper addSubview:self.searchController.searchBar];
  searchController.searchResultsController.view.hidden = NO;
}

-(void)willDismissSearchController:(UISearchController *)searchController{
    self.navigationController.navigationBar.translucent = NO;
    searchController.searchResultsController.view.hidden = NO;
}

But the search bar still disappears when touched. What else can I try?

I think the difference between my code and the rest of the posts is that I'm using a UIViewController created programmatically without a XIB. There is a UITableView child view, but it doesn't interact directly with the search bar. There is no UINavigationBar, the search bar is at the top of the view.

UPDATE:

This is my view hierarchy relative to the search bar:

- UIViewController 
 - UIView
  - UIScrollView
   - UIViewController
    - UIView
     - UISearchBar
3

3 Answers

1
votes

There are a couple of things I would suggest.

  1. in viewDidLoad

    // after creating the searchController add
    self.mySearchController.active = YES;
    
    // also add this for the search bar
    [self.mySearchController.searchBar setAutoresizingMask: UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    

I set up a simple test app. Added a UIView to the top (this will be the searchBarWrapper). Constrained top, leading, trailing and gave it a fixed height. Added a tableView below that, with a prototypeCell and constrained it Top,Leading,Trailing,Bottom --- plain simple nothing out of the ordinary. All works just fine.

i can post the whole viewControllerClass if you need it.

1
votes

I had the same exact problem. What fixed it for me was adding anchors to the searchBarWrapper, then adding them again in viewDidLayoutSubviews. Basically I had to add them twice:

@IBOutlet weak var searchBarWrapper: UIView!
fileprivate var searchController: UISearchController!

//MARK:- View Controller Lifecycle
override func viewDidLoad() {
        super.viewDidLoad()

        setSearchController()
}

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        positionSearchControllerInWrapperView()
}

//MARK:- Custom Funcs
fileprivate func setSearchController(){
        searchController = UISearchController(searchResultsController: nil)
        searchController.delegate = self
        searchController.searchBar.delegate = self
        searchController.searchResultsUpdater = self
        searchController.searchBar.showsCancelButton = false
        searchController.searchBar.placeholder = "Search man..."
        searchController.searchBar.returnKeyType = .done
        searchController.dimsBackgroundDuringPresentation = false
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.searchBar.endEditing(true)
        searchController.searchBar.sizeToFit()

        definesPresentationContext = true
        navigationItem.hidesBackButton = true

        positionSearchControllerInWrapperView()
}

//this gets called TWICE
fileprivate func positionSearchControllerInWrapperView(){
        searchBarWrapper.addSubview(searchController.searchBar)
        searchController.searchBar.translatesAutoresizingMaskIntoConstraints = false
        searchController.searchBar.leftAnchor.constraint(equalTo: searchBarWrapper.leftAnchor).isActive = true
        searchController.searchBar.rightAnchor.constraint(equalTo: searchBarWrapper.rightAnchor).isActive = true
        searchController.searchBar.topAnchor.constraint(equalTo: searchBarWrapper.topAnchor).isActive = true
        searchController.searchBar.bottomAnchor.constraint(equalTo: searchBarWrapper.bottomAnchor).isActive = true
}
0
votes

Hey if you are still seeking for a solution, just create a wrapper view and subview your searchbar to it:

UIView *searchWrapperView = [[UIView alloc] initWithFrame:(CGRect){0, 0, screenWidth, 44}];
[self.view addSubview:searchWrapperView];
[searchWrapperView addSubview:self.searchController.searchBar];