【问题标题】:UISearchController searchBar showsCancelButton not being respectedUISearchController searchBar 显示取消按钮不被尊重
【发布时间】:2020-06-04 07:59:12
【问题描述】:

我在我的应用程序中添加了一个 UISearchController,并将它的 searchBar 设置为我的 navigationItemtitleView

这可行,但尽管已将 showsCancelButton 设置为 false,但我看到了取消按钮。

    searchController = UISearchController(searchResultsController: searchResultsController)
    searchController.searchResultsUpdater = searchResultsUpdater


    // Configure the searchBar
    searchController.searchBar.placeholder = "Find Friends..."
    searchController.searchBar.sizeToFit()
    searchController.searchBar.showsCancelButton = false

    self.definesPresentationContext = true

    navigationItem.titleView = searchController.searchBar

【问题讨论】:

  • 你能发布更多你的代码吗?
  • 有什么特别的吗?
  • iOS 13 终于修复了这个问题。

标签: ios xcode swift


【解决方案1】:

我同意,这似乎是一个错误。问题是searchController 不断重置searchBar 的showsCancelButton 属性。我找到了一个解决方案,涉及:

  1. 子类化 UISearchBar 以忽略 setShowsCancelButton
  2. 要让 searchController 使用该子类,您必须继承 UISearchController
  3. 然后你发现searchBar并没有触发搜索控制器的委托方法,所以你必须单独触发它们......

令人费解,但似乎可以解决问题。你可以找到完整的answer here

【讨论】:

  • iOS 12.1 中仍未修复。
【解决方案2】:

这似乎是 iOS 中的一个错误。在 Apple 提供的示例项目中可以看到我描述的相同行为

https://developer.apple.com/library/ios/samplecode/TableSearch_UISearchController/Introduction/Intro.html

文档指出,默认值为NO,但似乎并非如此。设置showsCancelButtonNO 好像没有效果。

我已为此提交了一份雷达申请,正在等待回复。

【讨论】:

  • 苹果有没有就这个问题回复你?我仍然看到它发生在 8.4。
  • @vinnybad 不幸的是我还没有收到回复。如果我这样做,我一定会更新这个。
【解决方案3】:

Swift3 中的简单解决方案 - 我们需要使 CustomSearchBar 没有取消按钮,然后在新的 CustomSearchController 中覆盖相应的属性:

class CustomSearchBar: UISearchBar {

override func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool) {
    super.setShowsCancelButton(false, animated: false)
}}


class CustomSearchController: UISearchController {

lazy var _searchBar: CustomSearchBar = {
    [unowned self] in
    let customSearchBar = CustomSearchBar(frame: CGRect.zero)
    return customSearchBar
    }()

override var searchBar: UISearchBar {
    get {
        return _searchBar
    }
}}

在 MyViewController 中,我使用这个新的自定义子类初始化和配置 searchController:

    var mySearchController: UISearchController = ({
    // Display search results in a separate view controller
    //        let storyBoard = UIStoryboard(name: "Main", bundle: Bundle.main)
    //        let alternateController = storyBoard.instantiateViewController(withIdentifier: "aTV") as! AlternateTableViewController
    //        let controller = UISearchController(searchResultsController: alternateController)
    let controller = CustomSearchController(searchResultsController: nil)
    controller.searchBar.placeholder = NSLocalizedString("Enter keyword (e.g. iceland)", comment: "")
    controller.hidesNavigationBarDuringPresentation = false
    controller.dimsBackgroundDuringPresentation = false
    controller.searchBar.searchBarStyle = .minimal
    controller.searchBar.sizeToFit()
    return controller
})()

【讨论】:

    【解决方案4】:

    我不得不通过一些小技巧来纠正......

    在 viewDidLoad 上将 alpha 设置为 0.0,因为他的屏幕会闪烁。

    在你问之前...willPresentSearchController 将不起作用。

    extension GDSearchTableViewController: UISearchControllerDelegate {
        func didPresentSearchController(searchController: UISearchController) {
            searchController.searchBar.setShowsCancelButton(false, animated: false)
            searchController.searchBar.becomeFirstResponder()
            UIView.animateWithDuration(0.1) { () -> Void in
                self.view.alpha = 1.0
                searchController.searchBar.alpha = 1.0
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      我们希望搜索栏最初没有“取消”按钮,但在用户点击搜索栏时显示。 然后,如果用户点击取消,我们希望取消按钮消失,否则搜索栏会失去第一响应者。

      什么最终对我有用:

      创建时:

      searchBar.showsCancelButton = NO;
      

      我们使用 UISearchBar 的子类并覆盖 searchBarShouldBeginEditing:

      -(BOOL)searchBarShouldBeginEditing:(UISearchBar*)searchBar {
          self.showsCancelButton = YES;
          return YES;
      }
      

      我们也因此重写了 resignFirstReponder(在 UISearchBar 子类中):

      -(BOOL)resignFirstResponder
      {
          self.showsCancelButton = NO;
          return [super resignFirstResponder];
      }
      

      【讨论】:

        【解决方案6】:

        我还要补充

        searchController.hidesNavigationBarDuringPresentation = false
        searchController.delegate = self
        searchController.searchBar.delegate = self
        

        看看分配这些代表是否会有所帮助。

        【讨论】:

        • 已添加但无济于事
        • 只是添加“hidesNavigationBarDuringPresentation”可以防止搜索栏在聚焦时增长
        【解决方案7】:

        我想帮助你,但我不确定我是否找到了真正的问题。

        根据Apple Documentation

        showsCancelButton
        

        布尔属性,指示取消按钮是否为 显示

        但是为了隐藏取消按钮,也许你应该使用:

        setShowsCancelButton(_:animated:)
        

        希望对你有所帮助。

        【讨论】:

        • UISearchBar 的头文件指出showsCancelButton 的默认值是假的,所以大概我不需要做任何事情来隐藏它。
        • mmm 只是出于好奇,您是否尝试在 searchBarTextDidBeginEditing 等一些委托方法中使用 searchController.searchBar.showsCancelButton = false?在那种情况下它有效吗?
        • iOS13 崩溃了,直到在 setShowsCancelButton(_:animated:) 上替换调用 showsCancelButton
        【解决方案8】:

        您可以继承 UISearchBar 并覆盖方法layoutSubviews

        super.layoutSubviews()
        self.showsCancelButton = false
        

        【讨论】:

          【解决方案9】:

          我的解决方案是每次使用 searchcontroller 和它的搜索栏时都重新设置属性。我懒惰地初始化了searchcontroller,没有设置属性,然后做了

          searchController.searchBar.showsCancelButton = false
          

          每次搜索开始前。 您可以在 UISearchControllerDelegate 方法中执行此操作,即...

          【讨论】:

            【解决方案10】:

            这对我有用(iOS 10):

            - (void)viewWillAppear:(BOOL)animated {
                  [super viewWillAppear:animated];
                  self.searchController.searchBar.showsCancelButton = NO;
            }
            

            【讨论】:

              【解决方案11】:

              请注意,这在 iOS 13 上已更改,并在 showsCancelButton 上引用 Apple 的文档,目前仅在 UISearchBar.h 上可用,在 developer.apple.com 上不可用

              /* New behavior on iOS 13.
               If the search bar is owned by a UISearchController, then using the setter
               for this property (as well as -setShowsCancelButton:animated:) will implicitly
               set the UISearchController's automaticallyShowsCancelButton property to NO.
               */
              

              automaticallyShowsCancelButton 已在 iOS 13.0 中引入,应该澄清@pbasdf 在他的回答中已经指出的内容:错误行为是UISearchController 所固有的。

              【讨论】:

                【解决方案12】:

                【讨论】:

                • 你什么时候打电话?
                • viewDidLoad。不过这很奇怪,因为 showCancelButton 的默认值应该是 false,所以这无关紧要
                猜你喜欢
                • 1970-01-01
                • 2018-12-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多