4

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
Community
  • 1
  • 1
Cbas
  • 6,003
  • 11
  • 56
  • 87

3 Answers3

1

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.

MDB983
  • 2,444
  • 17
  • 20
  • didn't work for me, but maybe its due to something in my view hierarchy. I updated the question with it – Cbas Apr 06 '16 at 20:28
  • Ahh, yes that would have been helpful to know from the outset. There is a bug in which UISearchController does not properly handle the case where the view of the view controller presenting the UISearchController is inset from its superview. This may be part of the issue you're facing. – MDB983 Apr 06 '16 at 20:59
1

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
}
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
0

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];
Bob Bobster
  • 95
  • 1
  • 9