繁体   English   中英

iOS8无法隐藏UISearchController中搜索栏上的取消按钮

[英]iOS8 Cannot hide cancel button on search bar in UISearchController

我的目标是阻止取消按钮出现在UISearchController的搜索栏中。 我从Apple的Table Search开始, 使用UISearchController示例代码并隐藏了取消按钮,如下面的代码片段所示。 但是,当用户点击文本字段时,仍会显示取消按钮。 有帮助吗?

override func viewDidLoad() {
    super.viewDidLoad()

    resultsTableController = ResultsTableController()

    searchController = UISearchController(searchResultsController: resultsTableController)
    searchController.searchResultsUpdater = self
    searchController.searchBar.sizeToFit()
    tableView.tableHeaderView = searchController.searchBar

    searchController.searchBar.delegate = self

    //Hide cancel button - added by me
    searchController.searchBar.showsCancelButton = false

    ...

我认为有三种方法可以实现这一目标:

  1. 覆盖searchDisplayControllerDidBeginSearch并使用以下代码:

searchController.searchBar.showsCancelButton = false

  1. 子类UISearchBar并覆盖layoutSubviews以在系统尝试绘制var时更改该var。

  2. 注册键盘通知UIKeyboardWillShowNotification并应用第1点中的代码

当然可以随时实现您的搜索栏。

对于iOS 8,和UISearchController,使用该委托方法从UISearchControllerDelegate

func didPresentSearchController(searchController: UISearchController) {
  searchController.searchBar.showsCancelButton = false
}

不要忘记将自己设置为委托: searchController.delegate = self

简单地UISearchControllerUISearchBar

class NoCancelButtonSearchController: UISearchController {
    let noCancelButtonSearchBar = NoCancelButtonSearchBar()
    override var searchBar: UISearchBar { return noCancelButtonSearchBar }
}

class NoCancelButtonSearchBar: UISearchBar {
    override func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool) { /* void */ }
}

以下github项目子类UISearchBar,它作为解决方案2呈现:

https://github.com/mechaman/CustomSearchControllerSwift

除此之外,它还是UISearchController的子类,使得人们可以将搜索栏放在tableView标题以外的位置!

希望这可以帮助。

这是我在Swift中提出的最简单的解决方案。

定制搜索控制器:

class CustomSearchController: UISearchController {

    var _searchBar: CustomSearchBar

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        self._searchBar = CustomSearchBar()
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    override init(searchResultsController: UIViewController?) {
        self._searchBar = CustomSearchBar()
        super.init(searchResultsController: searchResultsController)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override var searchBar: UISearchBar {
        return self._searchBar
    }
}

自定义搜索栏:

class CustomSearchBar: UISearchBar {
    override func setShowsCancelButton(showsCancelButton: Bool, animated: Bool) {
        // do nothing
    }
}

其中最重要的部分是只在init创建一次_searchBar对象,而在存储的属性中创建它。

只需子类化您的UISearchController并执行以下操作:

class CustomSearchController: UISearchController {

   override func viewDidLayoutSubviews() {
       super.viewDidLayoutSubviews()
       searchBar.showsCancelButton = false
   }
}

这是我能想出的最简单的解决方案,以解决闪烁的取消按钮问题。

TL; DR :子类化UISearchBar并覆盖setShowsCancelButton:setShowsCancelButton:animated:隐藏取消按钮。

如果搜索栏不是第一个响应者(键盘未激活并显示),我将active设置为NO ,因为这实际上是取消命令。

FJSearchBar

标记searchController.searchBar.showsCancelButton = NO似乎在iOS 8中不起作用。 我还没有测试iOS 9

FJSearchBar.h

空,但放在这里是为了完整。

@import UIKit;

@interface FJSearchBar : UISearchBar

@end

FJSearchBar.m

#import "FJSearchBar.h"

@implementation FJSearchBar

- (void)setShowsCancelButton:(BOOL)showsCancelButton {
    // do nothing
}

- (void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated {
    // do nothing
}

@end

FJSearchController

这是你想要做出真正改变的地方。 我将UISearchBarDelegate拆分为自己的类别,因为恕我直言,这些类使类更清晰,更易于维护。 如果您希望将委托保留在主类接口/实现中,那么非常欢迎您这样做。

FJSearchController.h

@import UIKit;

@interface FJSearchController : UISearchController

@end

@interface FJSearchController (UISearchBarDelegate) <UISearchBarDelegate>

@end

FJSearchController.m

#import "FJSearchController.h"
#import "FJSearchBar.h"

@implementation FJSearchController {
@private
    FJSearchBar *_searchBar;
    BOOL _clearedOutside;
}

- (UISearchBar *)searchBar {
    if (_searchBar == nil) {
        // if you're not hiding the cancel button, simply uncomment the line below and delete the FJSearchBar alloc/init
        // _searchBar = [[UISearchBar alloc] init];
        _searchBar = [[FJSearchBar alloc] init];
        _searchBar.delegate = self;
    }
    return _searchBar;
}

@end

@implementation FJSearchController (UISearchBarDelegate)

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
    // if we cleared from outside then we should not allow any new editing
    BOOL shouldAllowEditing = !_clearedOutside;
    _clearedOutside = NO;
    return shouldAllowEditing;
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    // hide the keyboard since the user will no longer add any more input
    [searchBar resignFirstResponder];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    if (![searchBar isFirstResponder]) {
        // the user cleared the search while not in typing mode, so we should deactivate searching
        self.active = NO;
        _clearedOutside = YES;
        return;
    }
    // update the search results
    [self.searchResultsUpdater updateSearchResultsForSearchController:self];
}

@end

需要注意的部分内容:

  1. 我把搜索栏和BOOL作为私有变量而不是属性,因为
    • 它们比私有财产更轻量级。
    • 它们不需要被外界看到或修改。
  2. 我们检查searchBar是否是第一个响应者。 如果不是,那么我们实际上会停用搜索控制器,因为文本为空,我们不再搜索。 如果你真的想确定,你也可以确保searchText.length == 0
  3. searchBar:textDidChange:searchBarShouldBeginEditing:之前调用,这就是我们按此顺序处理它的原因。
  4. 我每次文本更改时都会更新搜索结果,但您可能想要移动[self.searchResultsUpdater updateSearchResultsForSearchController:self]; to searchBarSearchButtonClicked:如果您只想在用户按下“ 搜索”按钮后执行搜索

迅速:

以下为我工作,在viewDidLoad下添加,因为我从来不想要那个按钮:

let searchBarStyle = searchBar.value(forKey: "searchField") as? UITextField
searchBarStyle?.clearButtonMode = .never

确保在故事板中添加searchBar的ID。 在此输入图像描述

使用UISearchControllerDelegate。

func willPresentSearchController(_ searchController: UISearchController) {

        searchController.searchBar.setValue("", forKey:"_cancelButtonText")
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM