破碎的UIearchBar动画嵌入在NavigationItem中

我遇到了将搜索栏添加到导航项的新方法的问题。

正如您在下图中看到的,有两个UIViewControllers一个接一个,并且都有搜索栏。 问题是动画,当搜索栏在第一个视图控制器上可见但在第二个视图控制器上不可见时,这是丑陋的。 搜索栏占用的区域停留在屏幕上并突然消失。

演示

代码非常基本(项目中没有其他更改):

(我主要使用C#编写,因此此代码中可能存在错误。)

ViewController.swift:

import UIKit class ViewController: UITableViewController, UISearchResultsUpdating { override func loadView() { super.loadView() definesPresentationContext = true; navigationController?.navigationBar.prefersLargeTitles = true; navigationItem.largeTitleDisplayMode = .automatic; navigationItem.title = "VC" tableView.insetsContentViewsToSafeArea = true; tableView.dataSource = self; refreshControl = UIRefreshControl(); refreshControl?.addTarget(self, action: #selector(ViewController.handleRefresh(_:)), for: UIControlEvents.valueChanged) tableView.refreshControl = refreshControl; let stvc = UITableViewController(); stvc.tableView.dataSource = self; let sc = UISearchController(searchResultsController: stvc); sc.searchResultsUpdater = self; navigationItem.searchController = sc; } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCell(withIdentifier: "cell1"); if (cell == nil) { cell = UITableViewCell(style: .default, reuseIdentifier: "cell1"); } cell?.textLabel?.text = "cell " + String(indexPath.row); return cell!; } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20; } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let vc = ViewController(); navigationController?.pushViewController(vc, animated: true); } @objc func handleRefresh(_ refreshControl: UIRefreshControl) { DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2), execute: { refreshControl.endRefreshing(); }) } func updateSearchResults(for searchController: UISearchController) { } } 

AppDelegate.swift:

 import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds); window?.rootViewController = UINavigationController(rootViewController: ViewController()); window?.makeKeyAndVisible(); UINavigationBar.appearance().barTintColor = UIColor.red; return true } } 

想法?

看起来苹果仍然需要在新的大型标题风格中使用UISearchBar。 如果您推送到的UIViewController没有设置navigationItem.searchController ,则动画可以正常工作。 在两个都有searchController设置的UIViewController实例之间导航时,您会遇到导航栏高度跳跃的问题。

每次调用viewDidAppear (而不是在loadView中创建它)并在viewDidDisappear上将navigationItem.searchController设置为nil时,您可以通过创建UISearchController来解决(解决)问题。

 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) DispatchQueue.main.async { let stvc = UITableViewController() stvc.tableView.dataSource = self let sc = UISearchController(searchResultsController: stvc) sc.searchResultsUpdater = self self.navigationItem.searchController = sc } } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) self.navigationItem.searchController = nil } 

异步调度的原因是在viewDidAppear方法中内联设置navigationItem.searchController时会引发exception:

 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Only one palette with a top boundary edge can be active outside of a transition. Current active palette is <_uinavigationcontrollermanagedsearchpalette: 0x7fad67117e80; frame = (0 116; 414 0); layer = >' 

我知道这只是一个解决方法,但希望这对你现在有所帮助,直到Apple解决了两个视图控制器之间导航的问题,这两个视图控制器都在其navigationItem上设置了UISearchController

我在viewDidLoad()中添加了这段代码,当我移动标签的b / w时,它正在工作

 searchController.dimsBackgroundDuringPresentation 
Interesting Posts