UISearchBarController iOS 11 issue - SearchBar and scope buttons overlap

后端 未结 7 865
误落风尘
误落风尘 2021-01-04 07:26

Referred here and here. No answer in first link. In the second link, though the answer is not accepted, but the link to apple developer forum gives error.

Before i

相关标签:
7条回答
  • 2021-01-04 07:32

    I think that the solution is to add the Search Bar in the Navigation Bar:

    navigationController?.navigationBar.prefersLargeTitles = true // Navigation bar large titles
    navigationItem.title = "Contacts"
    navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.white]
    navigationController?.navigationBar.barTintColor = UIColor(displayP3Red: 0/255, green: 150/255, blue: 136/255, alpha: 1.0)
    
    let searchController = UISearchController(searchResultsController: nil) // Search Controller
    navigationItem.hidesSearchBarWhenScrolling = false
    navigationItem.searchController = searchController
    

    You can find an example for UISearchBarController - SearchBar and scope buttons overlap here.

    0 讨论(0)
  • 2021-01-04 07:35

    I can get the initial appearance to display correctly in iOS11 using the following code (as per greg's answer):

    [self.searchController.searchBar sizeToFit];
    
    if (@available(iOS 11.0, *)) {
        self.navigationItem.searchController = self.searchController;
        self.navigationItem.hidesSearchBarWhenScrolling = NO;
    } else {
        // Fallback on earlier versions
        self.tableView.tableHeaderView = self.searchController.searchBar;
    }
    

    However, if the app is backgrounded then restored while the search bar was active, the appearance would end up overlapped as shown in Nitish's second screenshot above.

    I was able to fix that with the following workaround:

    [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
        self.searchController.searchBar.showsScopeBar = NO;
        [self.searchController.searchBar sizeToFit];
        self.searchController.searchBar.showsScopeBar = YES;
        [self.searchController.searchBar sizeToFit];
    }];
    

    (I'm still working on how to workaround the layout issues following an interface orientation change while the search bar is active - that still ends up overlapped.)

    0 讨论(0)
  • 2021-01-04 07:40

    In the radar that Ray Wenderlich filed, @benck posted this answer from WWDC, which, if I'm not mistaken, hasn't been posted yet.

    0 讨论(0)
  • 2021-01-04 07:42

    Adding these lines fixed it for me:

    override func viewDidLayoutSubviews() {
        self.searchController.searchBar.sizeToFit()
    }
    
    0 讨论(0)
  • 2021-01-04 07:55

    Per your comments, your UISearchController's UISearchBar has been assigned to your UITableView's tableHeaderView. In iOS 11, you should instead be assigning your UISearchController to the searchController property of your view's navigationItem. You no longer need to assign the UISearchBar anywhere. See Apple's documentation on this new property.

    0 讨论(0)
  • 2021-01-04 07:56

    I met the same issue on my app, my solution is in iOS 11, using apple suggested new way for searchBar which is in navigationItem, otherwise, using the old way. My code in viewDidLoad() as below:

    if #available(iOS 11.0, *) {
        navigationController?.navigationBar.prefersLargeTitles = false
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
        searchViewHeight.constant = 0
    } else {
        searchView.addSubview(searchController.searchBar)
    }
    

    I have two IBOutlets: searchView and searchViewHeight:

    @IBOutlet var searchView: UIView!
    @IBOutlet var searchViewHeight: NSLayoutConstraint! // new added for iOS 11
    

    Before iOS 11, my viewController's hierarchy as below:

    My searchView before iOS 11

    I have a searchView which height is 44 to contains my searchController's searchBar view. It's under navigation bar.

    In iOS 11, I add a new IBOutlet for searchView's height constraint, and set its constant to 0, hide this container view. And add searchController as a part of navigation item.

    See apple's document: https://developer.apple.com/documentation/uikit/uinavigationitem/2897305-searchcontroller

    One more thing is under iOS 11, the searchBar's textField background color is little darker than navigation bar color by default. For consistency, you can change it to white, the below code will work both for iOS11 and its prior:

    if let textField = searchController.searchBar.value(forKey: "searchField") as? UITextField {
        if let backgroundView = textField.subviews.first {
    
            // Search bar textField background color
            backgroundView.backgroundColor = UIColor.white
    
            // Search bar textField rounded corner
            backgroundView.layer.cornerRadius = 10
            backgroundView.clipsToBounds = true
        }
    }
    
    0 讨论(0)
提交回复
热议问题