iOS 13 strange search controller gap

前端 未结 12 1724
无人共我
无人共我 2021-02-01 14:55

When running the App on iOS 13 beta 6, using Xcode 11 beta 5 I\'m encountering the strange gap when presenting search results view controller:

Here\'s a bit o

相关标签:
12条回答
  • 2021-02-01 15:36

    Just bringing my solution. In my case:

    edgesForExtendedLayout = .all
    

    on the UIViewController that contains the UISearchController worked.

    //MARK: - Properties
    var presenter: ExplorePresenting?
    var searchController: UISearchController?
    var searchUpdater: SearchUpdating?
    
    
    //MARK: - Lifecycle methods
    public override func viewDidLoad() {
        super.viewDidLoad()
    
        headerTitle = "explore".localised
        tableView.allowsSelection = false
        registerCell(cellClass: ExploreTableViewCell.self, with: tableView)
    
        if let searchController = searchController {
    
            searchController.searchBar.delegate = self
            searchController.searchResultsUpdater = self
            searchController.obscuresBackgroundDuringPresentation = false
            searchController.searchBar.placeholder = "explore_search_placeholder".localised
    
            definesPresentationContext = true
            navigationItem.hidesSearchBarWhenScrolling = false
            navigationItem.searchController = searchController
            edgesForExtendedLayout = .all
    
        }
    
        presenter?.viewReady()
    
    }
    
    0 讨论(0)
  • 2021-02-01 15:42

    Using .asyncAfter(deadline: .now() + 0.1) will cause a glitch in the UI. To get rid of that, get rid of the deadline! Using DispatchQueue.main.async is enough.

    extension UISearchController {
        open override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            if let presentingVC = self.presentingViewController {
                DispatchQueue.main.async {
                    self.view.frame = presentingVC.view.frame
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-01 15:47

    FYI I filed a bug report to apple - according to the WWDC presentation that describes the newly re-written SearchController and some other UI updates, it sounds like the architecture of the SearchController has been re-written from the ground up. I can't believe that this gap we are seeing is expected behavior - I've wasted the better part of two days trying to move past this, and I'm not bothering any further - my app store app is a free app that has a number of users and I wasn't able to devote time to tracking changes/behavior in the API during the beta period, I'm somewhat tired of Apple doing this kind of thing on a yearly basis.

    0 讨论(0)
  • 2021-02-01 15:47

    You must set yours navigationBar.standardAppearance to an UINavigationBarAppearance object that describes a white background.

    if #available(iOS 13.0, *) {
            let appearance = UINavigationBarAppearance()
            appearance.backgroundColor = .white
            self.navigationController?.navigationBar.standardAppearance = appearance
    }
    
    0 讨论(0)
  • 2021-02-01 15:49
    1. As it was mentioned in above answers, set Extend Edges Under Opaque Bars flag as On for UIViewController which presents search results. For me it was not enough because I use NOT translucent navigation bar.
    2. So I added the following implementation for methods of UISearchControllerDelegate:
        - (void)willPresentSearchController:(UISearchController *)searchController
        {
            if (@available(iOS 13.0, *))
            {
                self.navigationController.navigationBar.translucent = YES;
            }
        }
    
        - (void)willDismissSearchController:(UISearchController *)searchController
        {
            if (@available(iOS 13.0, *))
            {
                self.navigationController.navigationBar.translucent = NO;
            }
        }
    
    0 讨论(0)
  • 2021-02-01 15:49

    I finally solved this by replacing the UISearchController with a simple(r) UISearchBar.

    Maybe not the answer you wanted to hear, but the UISsearchController was already a mess on iOS12, the same code on iOS13 works but give horrible UI artifacts. Like disapearing or overlapping searchbar with the header, white space between the searchbar and the first element of the table, or hiding the first list-item under the scope buttons, ... All different issues between iOS12 and 13, but never looking good.

    So overall I spent 6 hours trying to fix the searchcontroller, failed, then spent 30 mins migrating to the Searchbar.

    I added the UISearchBar simply using Interface Builder in Xcode10.3. For the refactoring, mostly I had to simply replace searchController.searchBar.xx by searchBar.xx . The main effort was to reimplement the UISeachBarDelegates. Just to only show the scopebuttons and cancel button while the user is searching, and removing them afterwards. The code below gives a good overview of what I did:

    class MasterViewController: UITableViewController, NSFetchedResultsControllerDelegate {
    
      var fetchedItemsController: NSFetchedResultsController<Item>! = NSFetchedResultsController()
    
      @IBOutlet weak var searchBar: UISearchBar! //hooked up to IB
      //GONE IS: let searchController = UISearchController(searchResultsController: nil)
    
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        initializeFetchedResultsControllerForItems()
    
        //Enable search controller
        searchBar.scopeButtonTitles = [NSLocalizedString("Name", comment: ""),
                                       NSLocalizedString("Birthdate", comment: ""),
                                       NSLocalizedString("Employer", comment: "")    ]
        searchBar.placeholder = NSLocalizedString("Search", comment: "")
        searchBar.delegate = self
        searchBar.showsScopeBar = false
        searchBar.showsCancelButton = false
    
        tableView.contentInsetAdjustmentBehavior = .automatic
        self.tableView.tableHeaderView = searchBar //add the searchbar as tableheader view
    
        self.initializeFetchedResultsControllerForItems()
    
      }
    
      // MARK: - Data loading from CoreData
      private func initializeFetchedResultsControllerForItems(searchText: String = "", scopeIndex: Int = 0) {
        //print("FETCH RESULTS WITH FILTER: \(searchText) en SCOPE: \(scopeIndex)")
        //Do whatever searches you need to do to update the FetchedResultsController
        //..
        self.tableView.reloadData()
      }
    }
    
    extension MasterViewController: UISearchBarDelegate {  //the delegates for the searchbar
      func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        searchBar.showsScopeBar = true  //show the scopebar when users adds text to searchbar
        searchBar.showsCancelButton = true //also show the cancel button
        searchBar.sizeToFit()
        self.tableView.reloadData() //since the scopebar is there, the table needs to move a bit down
    
      }
      func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
      }
      func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: searchBar.selectedScopeButtonIndex)
      }
      func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        switch (selectedScope) {
        case 0: searchBar.placeholder = NSLocalizedString("Seach on name", comment: "")
        case 1: searchBar.placeholder = NSLocalizedString("Search on birthdate", comment: "")
        case 2: searchBar.placeholder = NSLocalizedString("Search on employer", comment: "")
        default: searchBar.placeholder = NSLocalizedString("Search", comment: "")
    
        searchBar.showsScopeBar = true
        searchBar.sizeToFit()
        }
    
        initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: selectedScope)
      }
      func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.placeholder = NSLocalizedString("Search", comment: "")
        searchBar.showsScopeBar = false
        searchBar.showsCancelButton = false
        searchBar.endEditing(true)
        searchBar.text = ""
        searchBar.sizeToFit()
        initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: searchBar.selectedScopeButtonIndex)
      }
    }
    
    0 讨论(0)
提交回复
热议问题