我的目标是阻止取消按钮出现在UISearchController的搜索栏中。我从Apple's Table Search with UISearchController sample code开始并隐藏了取消按钮,如下面的代码片段所示。但是,当用户点击文本字段时,仍会显示取消按钮。有什么帮助吗?
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
...
答案 0 :(得分:17)
我认为有三种方法可以实现这一目标:
searchController.searchBar.showsCancelButton = false
子类UISearchBar并覆盖layoutSubviews以在系统尝试绘制var时更改该变量。
注册键盘通知 UIKeyboardWillShowNotification 并将代码应用于 1。
当然可以随时实现您的搜索栏。
答案 1 :(得分:17)
对于iOS 8和UISearchController,请使用UISearchControllerDelegate
中的此委托方法:
func didPresentSearchController(searchController: UISearchController) {
searchController.searchBar.showsCancelButton = false
}
不要忘记将自己设置为委托:searchController.delegate = self
答案 2 :(得分:12)
简单地继承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 */ }
}
答案 3 :(得分:3)
以下github项目子类UISearchBar,显示为解决方案2:
https://github.com/mechaman/CustomSearchControllerSwift
除此之外,它还是UISearchController的子类,使其能够将搜索栏放在tableView标题以外的位置!
希望这有帮助。
答案 4 :(得分:2)
这是我在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
}
}
最重要的一点是只在_searchBar
中创建一次init
对象,而不是在存储的属性中创建它。
答案 5 :(得分:2)
只需将UISearchController子类化并执行以下操作:
class CustomSearchController: UISearchController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
searchBar.showsCancelButton = false
}
}
这是我能想出的最简单的解决方案,以解决闪烁的取消按钮问题。
答案 6 :(得分:1)
<强> TL; DR 强>:
子类化UISearchBar
并覆盖setShowsCancelButton:
和setShowsCancelButton:animated:
会隐藏取消按钮。
如果搜索栏不是第一个响应者(键盘未处于活动状态并显示),我将active
设置为NO
,因为这实际上是取消命令。 / p>
标记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];
移至searchBarSearchButtonClicked:
按钮。答案 7 :(得分:0)
使用UISearchControllerDelegate。
pod
答案 8 :(得分:0)