[英]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.