嵌入在 NavigationItem 中的损坏的 UISearchBar 动画 [英] Broken UISearchBar animation embedded in NavigationItem

查看:24
本文介绍了嵌入在 NavigationItem 中的损坏的 UISearchBar 动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am experiencing a problem with the new way of adding search bar to the navigation item.

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

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 来解决(变通)问题(而不是在 loadView 中创建它)并在 viewDidDisappear 上将 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 解决了在两个视图控制器之间导航的问题,这两个视图控制器都在它们的 上设置了 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.

这篇关于嵌入在 NavigationItem 中的损坏的 UISearchBar 动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆