Reputation: 5180
I have a UISearchDisplayController and UISearchBar hooked up to my ViewController via Outlets from my nib.
I'd like to hide the cancel button so that the user never sees it. The problem is that the following code hides the button, but only after displaying it to the user for a millisecond (e.g., it flashes on the simulator and device and then disappears out of view).
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller
{
controller.searchBar.showsCancelButton = NO;
}
Is there a better way to hide it?
Upvotes: 28
Views: 26738
Reputation: 1013
On iOS 13.0 and later, UISearchController has this property you can use:
@property (nonatomic) BOOL automaticallyShowsCancelButton API_AVAILABLE(ios(13.0)); // Default YES
Upvotes: 0
Reputation: 125
After UISearchDisplayController deprecated in iOS8, Apple give handle search presentation to UISearchControllerDelegate.
so you can override searchBar to hide the Cancel button, like below :
- (void)didPresentSearchController:(UISearchController *)searchController {
[searchController.searchBar setShowsCancelButton:NO];
}
if you need hidden Cancel button from inactive state, you need set searchBar on init :
search = [[UISearchController alloc] initWithSearchResultsController:nil];
[search.searchBar setShowsCancelButton:NO];
Upvotes: 0
Reputation: 16336
Had this problem when using the UISearchBar
with UISearchController
. I'm using my own cancel button, as the cancel button wasn't showing on iPad with showsCancelButton = YES
, now it won't hide on iPhone with showsCancelButton = NO
!
The following worked for me.
Set the delegate, and initial value:
- (void)viewDidLoad
{
// ...
self.searchController.searchBar.showsCancelButton = NO;
self.searchController.searchBar.delegate = self;
}
Reset showsCancelButton
to NO
0.1s after the text bar begins editing.
#pragma mark - UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
self.searchController.searchBar.showsCancelButton = NO;
});
}
Upvotes: 3
Reputation: 20710
If you want to avoid the subclassing, implement
searchController.searchBar.showsCancelButton = false;
in these two delegate methods (Do not forget to assign delegates):
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
- (void)didPresentSearchController:(UISearchController *)searchController
The first one is called everytime you update the searchBar (Cancel button is visible by default) and the second one is for the first searchBar activation.
Upvotes: 2
Reputation: 8610
class CustomSearchBar: UISearchBar {
override func setShowsCancelButton(showsCancelButton: Bool, animated: Bool) {
super.setShowsCancelButton(false, animated: false)
}
}
class CustomSearchController: UISearchController, UISearchBarDelegate {
lazy var _searchBar: CustomSearchBar = {
[unowned self] in
let customSearchBar = CustomSearchBar(frame: CGRectZero)
customSearchBar.delegate = self
return customSearchBar
}()
override var searchBar: UISearchBar {
get {
return _searchBar
}
}
}
Upvotes: 3
Reputation: 912
If the cancel button shows up when editing the search field of the search bar you could do the following; subclass the search bar and have it implement the UITextFieldDelegate
protocol:
@interface CustomAlignedSearchBar : UISearchBar<UITextFieldDelegate>
Then implement textFieldDidBeginEditing:
and do something like:
- (void)textFieldDidBeginEditing:(UITextField *)textField{
[self setShowsCancelButton:self.cancelButtonShown animated:NO];
}
This will make sure that the cancel button will not show up.
Upvotes: 0
Reputation: 557
I had the same issue, but fixed it a different way.
For those who can't or don't want to subclass UISearchDisplayController
, I fixed the issue by adding a listener on UIKeyboardWillShowNotification
, and setting [self setShowsCancelButton:NO animated:NO]
there.
In viewWillAppear:
:
// Add keyboard observer:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillAppear:)
name:UIKeyboardWillShowNotification
object:nil];
Then you create:
- (void)keyboardWillAppear:(NSNotification *)notification
{
[YOUR-SEARCHBAR-HERE setShowsCancelButton:NO animated:NO];
}
Don't forget to add,
[[NSNotificationCenter defaultCenter] removeObserver:self];
in viewWillDisappear:
!
Hope this helps!
Upvotes: 15
Reputation: 438
Similar to Nimrod's answer, you can also subclass UISearchDisplayController
and implement the setActive:animated:
method:
- (void)setActive:(BOOL)visible animated:(BOOL)animated {
[super setActive:visible animated:animated];
self.searchBar.showsCancelButton = NO;
}
Upvotes: 7
Reputation: 650
I managed to hide the "Cancel" button by subclassing UISearchBar
and override this method:
-(void)layoutSubviews{
[super layoutSubviews];
[self setShowsCancelButton:NO animated:NO];
}
Upvotes: 39
Reputation: 5180
This seems to be a bug within Xcode. I submitted this error to Apple's bug reporting site, and they've followed up asking for more sample code and use-cases.
Thanks everyone for your attempt at solving this problem.
Upvotes: 6
Reputation: 422
Just based on issues I've had before have you tried setting it in:
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
I don't know how to ask this question in your question sorry if this is out of place.
Upvotes: 0