问题描述
我遇到了将搜索栏添加到导航项的新方法的问题。
I am experiencing a problem with the new way of adding search bar to the navigation item.
如下图所示,有两个UIViewControllers在另一个之后,两者都有搜索栏。问题是动画,当搜索栏在第一个视图控制器上可见但在第二个视图控制器上不可见时,这是丑陋的。搜索栏占据的区域停留在屏幕上并突然消失。
As you can see in the picture below, there are two UIViewControllers one after the other, and both have the search bar. The problem is the animation, which is ugly when search bar is visible on the first view controller but not on the second one. The area occupied by the search bar stays on the screen and suddenly disappears.
代码非常基本(项目中没有其他变化):
The code is very basic (no other changes in the project were made):
(我主要用C#编写,所以这段代码可能有错误。)
(I write primarily in C#, so there might be errors in this code.)
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
实例之间导航时,您会遇到导航栏高度跳跃的问题。
It looks like Apple still needs to iron out the use of the UISearchBar in the new large title style. If the UIViewController
you push to doesn't have its navigationItem.searchController
set, the animation works fine. When navigating between two instances of UIViewController
that both have a searchController set, you get the issue you describe where the height of the navigation bar jumps.
每次 viewDidAppear
获取时,您可以通过创建 UISearchController
来解决(解决)问题在 viewDidDisappear中调用(而不是在
。 loadView
中创建它)并将 navigationItem.searchController
设置为nil
You can solve (work around) the problem by creating the UISearchController
every time viewDidAppear
gets called (instead of creating it in loadView
) and setting navigationItem.searchController
to nil on viewDidDisappear
.
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
内联时,引发异常:
The reason for the asynchronous dispatch is that when setting the navigationItem.searchController
inline in the viewDidAppear
method, an exception is raised:
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 = <CALayer: 0x60400002c8e0>>'
我知道这只是一种解决方法,但是希望这对你现在有所帮助,直到Apple解决了两个视图控制器之间导航的问题,这两个视图控制器都在 navigationItem上设置了
。 UISearchController
I know this is only a work around, but hopefully this will help you for now, until Apple solves the issue with navigating between two view controllers that both have a UISearchController
set on their navigationItem
.
这篇关于破碎的UIearchBar动画嵌入在NavigationItem中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!