【问题标题】:iOS 11 UINavigationBar UISearchBar and UIBarButtonItem overlapiOS 11 UINavigationBar UISearchBar 和 UIBarButtonItem 重叠
【发布时间】:2018-01-10 15:14:31
【问题描述】:

在 iOS 11 中,如果将 UISearchBar 设置为 navigationItem 的 titleView。然后将 UIBarButtonItem 添加/删除到 navigationItem.leftBarButtonItems。 UIBarButtonItem 将与 UISearchBar 重叠。

重现步骤:

  1. 新建单视图 Xcode 项目
  2. 在 Storyboard 的 UINavigationController 中嵌入 ViewController
  3. 像这样修改 ViewController.swift

    class ViewController: UIViewController {
        let button = UIBarButtonItem(barButtonSystemItem: .add, target: nil, action: nil)
        override func viewDidLoad() {
            super.viewDidLoad()
            let searchBar = UISearchBar()
            searchBar.searchBarStyle = .minimal
            navigationItem.titleView = searchBar
        }
    
        override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
            super.traitCollectionDidChange(previousTraitCollection)
            if traitCollection.horizontalSizeClass == .regular {
                navigationItem.leftBarButtonItem = button
            } else {
                navigationItem.leftBarButtonItem = nil
            }
        }
    }
    

环境:Xcode 9.2、iOS 11.2.2

我的问题是:UINavigationBar 有没有办法正确布局项目,或者我在这里做错了什么?谢谢!

【问题讨论】:

    标签: ios uinavigationbar uisearchbar ios11 uibarbuttonitem


    【解决方案1】:

    试试 DispatchQueue.main.async

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        DispatchQueue.main.async {
            if self.traitCollection.horizontalSizeClass == .regular {
                self.navigationItem.leftBarButtonItem = self.button
            } else {
                self.navigationItem.leftBarButtonItem = nil
            }
        }
    }
    

    【讨论】:

    • 不幸的是,每次将应用程序从后台带到前台时,重叠都会再次发生。在使用多任务处理时也是如此。我试图通过在需要时重新配置异步块中的条形按钮来解决它。
    • 我必须在viewWillTransitionToSize 中使用DispatchQueue.main.async 再次配置按钮,并且当应用程序进入前台时。 Apple 的 QA 会发生什么变化?
    • 我觉得没问题
    【解决方案2】:
    override func viewDidLoad() {
        super.viewDidLoad()
    
        navigationController?.setNavigationBarHidden(true, animated: false)
        navigationController?.setNavigationBarHidden(false, animated: true)
    }
    

    【讨论】:

      【解决方案3】:

      重置viewWillAppear中的navigationItem.titleView

      设置titleView = nil 并返回搜索栏强制导航栏重新布局。

      类似:

      override func viewWillAppear(_ animated: Bool) {
          super.viewWillAppear(animated)
      
          navigationItem.titleView = nil
          navigationItem.titleView = self.searchBar
      }
      

      更多详情

      我喜欢使用traitCollectionDidChange 的公认解决方案。

      但是,该解决方案不适用于(并且仅适用于!)iPhone 11 Pro Max(目前为 iOS 14.4)。

      这是一个非常奇怪的问题,但viewWillAppear 中的重置是我发现适用于所有设备的唯一可靠解决方案。

      【讨论】:

        猜你喜欢
        • 2018-02-10
        • 2015-12-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-29
        • 1970-01-01
        • 1970-01-01
        • 2022-11-10
        • 1970-01-01
        相关资源
        最近更新 更多