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

如下图所示,有两个UIViewController,一个接一个,两个都有搜索栏。问题是动画,当搜索栏在第一个 View Controller 上可见而不在第二个 View Controller 上可见时,动画很难看。搜索栏占据的区域停留在屏幕上,然后突然消失。

ios - 嵌入在NavigationItem中的 splinter 的UISearchBar动画-LMLPHP

该代码非常基础(项目中未进行其他任何更改):

(我主要使用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的两个实例之间导航时,遇到描述导航栏高度跳到哪里的问题。

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

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
}

进行异步分派(dispatch)的原因是,在navigationItem.searchController方法中内联设置viewDidAppear时,会引发异常:
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通过在两个都设置了UISearchControllernavigationItem的 View Controller 之间导航来解决该问题为止。

关于ios - 嵌入在NavigationItem中的 splinter 的UISearchBar动画,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46301813/

10-12 14:46