簡體   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