iOS8无法在UISearchController的search栏上隐藏取消button
我的目标是防止取消button出现在UISearchController的search栏中。 我使用UISearchController示例代码从Apple的Table Search开始,并隐藏了取消button,如下面的代码片段所示。 但是,当用户点击文本字段时,取消button仍然出现。 任何帮助?
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 ...
我认为有三种方法可以达到这个目的:
- 重写searchDisplayControllerDidBeginSearch并使用以下代码:
searchController.searchBar.showsCancelButton = false
-
子类UISearchBar并覆盖layoutSubviews以在系统尝试绘制该variables时更改该variables。
-
注册键盘通知UIKeyboardWillShowNotification并应用第1点中的代码。
当然可以随时执行您的search栏。
对于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作为解决scheme2提供:
https://github.com/mechaman/CustomSearchControllerSwift
最重要的是,它也是UISearchController的子类,使其能够将search栏放在tableView标题以外的地方!
希望这可以帮助。
TL; DR :inheritanceUISearchBar
并覆盖setShowsCancelButton:
和setShowsCancelButton:animated:
隐藏取消button。
解
如果search栏不是第一个响应者(键盘未激活并显示),我将其设置为NO
,因为这实际上是取消命令。
FJSearchBar
标记searchController.searchBar.showsCancelButton = NO
似乎不适用于iOS 8 。 我还没有testingiOS 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
有些部分要注意:
- 我已经把search栏和
BOOL
作为私有variables,而不是属性,因为- 他们比私有财产更轻量。
- 他们不需要被外界看到或修改。
- 我们检查
searchBar
是否是第一个响应者。 如果不是,那么我们实际上停用search控制器,因为文本是空的,我们不再search。 如果你真的想确定,你也可以确保searchText.length == 0
。 -
searchBar:textDidChange:
在searchBarShouldBeginEditing:
之前被调用,这就是为什么我们按这个顺序处理它的原因。 - 我每次更新文本都会更新search结果,但是您可能需要移动
[self.searchResultsUpdater updateSearchResultsForSearchController:self];
searchBarSearchButtonClicked:
如果您只想在用户按下searchbutton后执行search 。
这是我能在Swift中想到的最简单的解决scheme。
自定义search控制器
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 } }
自定义search栏:
class CustomSearchBar: UISearchBar { override func setShowsCancelButton(showsCancelButton: Bool, animated: Bool) { // do nothing } }
其中最重要的部分是只在init
创build_searchBar
对象,而不是在存储属性中创build它。
使用UISearchControllerDelegate。
func willPresentSearchController(_ searchController: UISearchController) { searchController.searchBar.setValue("", forKey:"_cancelButtonText") }
只是你的UISearchController子类,并执行以下操作:
class CustomSearchController: UISearchController { override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() searchBar.showsCancelButton = false } }
这是我想出的最简单的解决scheme,以解决闪烁的取消button问题。
- 无法呈现多边形(无法保留指示:XX):featureID:X key:XXXX
- IOS使用NDHTMLtoPDF库将HTML页面转换为PDF
- 如何删除iMessage应用
- Swift Timer.scheduledTimer()不起作用
- UITabbarController与MoreNavigationController,PoptoRootViewController问题
- CVPixelBuffer到CIImage总是返回零
- 启动一个AVAssetReader,停止对远程I / O AudioUnit的callback
- 来自AnyObject的Swift,Self
- CSS背景延伸到填充iOS的高度,但滚动上有空白