破碎的UIearchBar动画嵌入在NavigationItem中 [英] Broken UISearchBar animation embedded in NavigationItem

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

问题描述

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

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中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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