UISearchController禁用取消UIBarButtonItem

sim*_*per 10 objective-c uikit uisearchbar ios uisearchcontroller

问题

我试图使用UISearchController在地图视图上搜索目的地.我希望UISearchBar出现在导航栏中,但我似乎无法在没有显示右侧的取消按钮的情况下这样做:

在此输入图像描述

这个取消按钮有时会消失,而我正在玩耍,但我现在无法让它显示我的搜索表显示我想要它:

在此输入图像描述

我肯定必须有一些我做得有点小错误的东西,但我无法弄清楚它是什么......

我的守则

self.resultsViewController = [UITableViewController new];
self.searchController = [[UISearchController alloc] initWithSearchResultsController:self.resultsViewController];
self.searchController.searchResultsUpdater = self;
self.searchController.hidesNavigationBarDuringPresentation = false;
self.searchController.delegate = self;
self.searchBar = self.searchController.searchBar;
self.searchBar.placeholder = self.stage.title;
self.searchBar.searchBarStyle = UISearchBarStyleMinimal;

self.definesPresentationContext = true;
self.navigationItem.titleView = self.searchBar;

self.resultsTableView = self.resultsViewController.tableView;
self.resultsTableView.dataSource = self;
self.resultsTableView.delegate = self;
Run Code Online (Sandbox Code Playgroud)

And*_*son 20

有一种更简单的方法......

对于iOS 8和UISearchController,请使用以下的委托方法UISearchControllerDelegate:

func didPresentSearchController(searchController: UISearchController) {
  searchController.searchBar.showsCancelButton = false
}
Run Code Online (Sandbox Code Playgroud)

不要忘记将自己设置为代表: searchController.delegate = self

  • 这种作品,但取消按钮在消失前简要显示. (15认同)

pba*_*sdf 13

根据评论更新

UISearchBar有一个属性(请参阅Apple文档),它确定是否显示取消按钮:

self.searchBar.showsCancelButton = false;
Run Code Online (Sandbox Code Playgroud)

但是,根据OP注释,这不起作用,因为searchController不断重新打开取消按钮.要避免这种情况,请创建UISearchBar的子类,并覆盖这些setShowsCancelButton方法:

@implementation MySearchBar

-(void)setShowsCancelButton:(BOOL)showsCancelButton {
    // Do nothing...
}

-(void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated {
    // Do nothing....
}

@end
Run Code Online (Sandbox Code Playgroud)

为了确保searchController使用此子类,我们还需要子类化UISearchController,并覆盖该searchBar方法以返回子类的实例.我们还需要确保新的searchBar激活searchController - 我选择使用这个UISearchBarDelegate方法textDidChange:

@interface MySearchController ()  <UISearchBarDelegate> {
UISearchBar *_searchBar;
}
@end

@implementation MySearchController

-(UISearchBar *)searchBar {
    if (_searchBar == nil) {
        _searchBar = [[MySearchBar alloc] initWithFrame:CGRectZero];
        _searchBar.delegate = self;
    }
    return _searchBar;
}

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    if ([searchBar.text length] > 0) {
        self.active = true;
    } else {
        self.active = false;
    }
}
@end
Run Code Online (Sandbox Code Playgroud)

最后,更改代码以实例化此子类:

self.searchController = [[MySearchController alloc] initWithSearchResultsController:self.resultsViewController];
Run Code Online (Sandbox Code Playgroud)

(您显然需要导入这些子类的相关头文件).


Vit*_*pov 13

Swift3中的简单解决方案- 我们需要使用CustomSearchBar而不使用取消按钮,然后覆盖新CustomSearchController中的相应属性:

class CustomSearchBar: UISearchBar {

override func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool) {
    super.setShowsCancelButton(false, animated: false)
}}

class CustomSearchController: UISearchController {
lazy var _searchBar: CustomSearchBar = {
    [unowned self] in
    let customSearchBar = CustomSearchBar(frame: CGRect.zero)
    return customSearchBar
    }()

override var searchBar: UISearchBar {
    get {
        return _searchBar
    }
}}
Run Code Online (Sandbox Code Playgroud)

在MyViewController中,我使用这个新的自定义子类初始化和配置searchController:

    var videoSearchController: UISearchController = ({
    // Display search results in a separate view controller
    //        let storyBoard = UIStoryboard(name: "Main", bundle: Bundle.main)
    //        let alternateController = storyBoard.instantiateViewController(withIdentifier: "aTV") as! AlternateTableViewController
    //        let controller = UISearchController(searchResultsController: alternateController)
    let controller = CustomSearchController(searchResultsController: nil)
    controller.searchBar.placeholder = NSLocalizedString("Enter keyword (e.g. iceland)", comment: "")
    controller.hidesNavigationBarDuringPresentation = false
    controller.dimsBackgroundDuringPresentation = false
    controller.searchBar.searchBarStyle = .minimal
    controller.searchBar.sizeToFit()
    return controller
})()
Run Code Online (Sandbox Code Playgroud)

它运作正常,顺畅

  • 与Swift 4.2和iOS 11/12一起使用也很完美. (3认同)