[英]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
...
我认为有三种方法可以实现这一目标:
searchController.searchBar.showsCancelButton = false
子类UISearchBar并覆盖layoutSubviews以在系统尝试绘制var时更改该var。
注册键盘通知UIKeyboardWillShowNotification并应用第1点中的代码。
当然可以随时实现您的搜索栏。
对于iOS 8,和UISearchController,使用该委托方法从UISearchControllerDelegate
:
func didPresentSearchController(searchController: UISearchController) {
searchController.searchBar.showsCancelButton = false
}
不要忘记将自己设置为委托: searchController.delegate = self
简单地UISearchController
和UISearchBar
。
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
,因为这实际上是取消命令。
标记searchController.searchBar.showsCancelButton = NO
似乎在iOS 8中不起作用。 我还没有测试iOS 9 。
空,但放在这里是为了完整。
@import UIKit;
@interface FJSearchBar : UISearchBar
@end
#import "FJSearchBar.h"
@implementation FJSearchBar
- (void)setShowsCancelButton:(BOOL)showsCancelButton {
// do nothing
}
- (void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated {
// do nothing
}
@end
这是你想要做出真正改变的地方。 我将UISearchBarDelegate
拆分为自己的类别,因为恕我直言,这些类使类更清晰,更易于维护。 如果您希望将委托保留在主类接口/实现中,那么非常欢迎您这样做。
@import UIKit;
@interface FJSearchController : UISearchController
@end
@interface FJSearchController (UISearchBarDelegate) <UISearchBarDelegate>
@end
#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
需要注意的部分内容:
BOOL
作为私有变量而不是属性,因为
searchBar
是否是第一个响应者。 如果不是,那么我们实际上会停用搜索控制器,因为文本为空,我们不再搜索。 如果你真的想确定,你也可以确保searchText.length == 0
。 searchBar:textDidChange:
在searchBarShouldBeginEditing:
之前调用,这就是我们按此顺序处理它的原因。 [self.searchResultsUpdater updateSearchResultsForSearchController:self];
to searchBarSearchButtonClicked:
如果您只想在用户按下“ 搜索”按钮后执行搜索 。 使用UISearchControllerDelegate。
func willPresentSearchController(_ searchController: UISearchController) {
searchController.searchBar.setValue("", forKey:"_cancelButtonText")
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.