web-dev-qa-db-ja.com

iOS 13の奇妙な検索コントローラーのギャップ

IOS 13ベータ6でアプリを実行しているときに、Xcode 11ベータ5を使用すると、検索結果のビューコントローラーを表示するときに奇妙なギャップが発生します。

enter image description here

これがどのように設定されているかを以下に示します。

let searchResultsController = BLSearchResultsController()

let ret = UISearchController(searchResultsController: searchResultsController)
ret.searchResultsUpdater = self
ret.delegate = self
ret.searchBar.delegate = self;
ret.searchBar.autocapitalizationType = .none
ret.searchBar.placeholder = NSLocalizedString("SearchMsg", comment: "")
        ret.searchBar.enablesReturnKeyAutomatically = true

if #available(iOS 13.0, *) {
    ret.searchBar.showsScopeBar = false
    ret.searchBar.backgroundColor = .white

    let searchTextField = ret.searchBar.searchTextField
    searchTextField.font = UIFont.tuttiRegularFont(16)
    searchTextField.accessibilityIdentifier = "Main Search Field"
    if let searchImageView = searchTextField.leftView as? UIImageView {
        searchImageView.image = UIImage(named: "home-search-icon")
     }
}

結果検索コントローラーは通常のUITableViewControllerであり、navigationItem.searchControllerに追加されるだけです。派手なプレゼンテーションコードはありません。最新のライブXcodeでビルドし、iOS 11/12デバイスで実行する場合、この問題は存在しないため、根本的なiOS 13の変更がこの不具合の原因である可能性があります。

ビュー階層をデバッグするとき、結果のビューコントローラーが移動した検索バーの最上部に達していないように見えます。

私はmodalPresentationModesをいじくり回して、プレゼンテーションへの変更が原因である可能性を排除しようとしましたが、そこに運がありませんでした。

誰かがこの問題に遭遇し、幸運にそれを修正しましたか?

28
UrosMi

最後に、UISearchControllerをsimple(r)UISearchBarに置き換えることでこれを解決しました。

多分あなたが聞きたかった答えではないかもしれませんが、UISsearchControllerはすでにiOS12では混乱しています。iOS13の同じコードは機能しますが、恐ろしいUIアーティファクトを与えます。検索バーをヘッダーと重ねて表示しない、またはオーバーラップするように、検索バーとテーブルの最初の要素の間に空白を入れたり、スコープボタンの下に最初のリストアイテムを非表示にしたりします。

そのため、全体として、検索コントローラーを修正するために6時間を費やし、失敗してから、30分かけて検索バーに移行しました。

Xcode10.3のInterface Builderを使用してUISearchBarを追加しました。リファクタリングでは、ほとんどの場合、単純にsearchController.searchBar .xxをsearchBar.xxに置き換える必要がありました。主な取り組みは、UISeachBarDelegatesを再実装することでした。ユーザーが検索しているときにスコープボタンとキャンセルボタンのみを表示し、後でそれらを削除するだけです。以下のコードは私がしたことの良い概要を示しています:

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
Rodge

ちょうど私のソリューションをもたらします。私の場合:

edgesForExtendedLayout = .all

uISearchControllerを含むUIViewControllerで動作しました。

//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
Reimond Hill

NavigationBar.standardAppearanceを、白い背景を表すUINavigationBarAppearanceオブジェクトに設定する必要があります。

if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.backgroundColor = .white
        self.navigationController?.navigationBar.standardAppearance = appearance
}
0
user3187971

.asyncAfter(deadline: .now() + 0.1)を使用すると、UIでグリッチが発生します。それを取り除くために、締め切りを取り除く! DispatchQueue.main.asyncを使用するだけで十分です。

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
Tiziano Coroneo