UISearchbar clearButton forces the keyboard to appear
This is an old question and I just came across the same issue and managed to solve it the following way:
When the searchBar:textDidChange:
method of the UISearchBarDelegate gets called because of the user tapping the 'clear' button, the searchBar hasn't become the first responder yet, so we can take advantage of that in order to detect when the user in fact intended to clear the search and not bring focus to the searchBar and/or do something else.
To keep track of that, we need to declare a BOOL
ivar in our viewController that is also the searchBar delegate (let's call it shouldBeginEditing
) and set it with an initial value of YES
(supposing our viewController class is called SearchViewController):
@interface SearchViewController : UIViewController <UISearchBarDelegate> {
// all of our ivar declarations go here...
BOOL shouldBeginEditing;
....
}
...
@end
@implementation SearchViewController
...
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
...
shouldBeginEditing = YES;
}
}
...
@end
Later on, in the UISearchBarDelegate, we implement the searchBar:textDidChange:
and searchBarShouldBeginEditing:
methods:
- (void)searchBar:(UISearchBar *)bar textDidChange:(NSString *)searchText {
NSLog(@"searchBar:textDidChange: isFirstResponder: %i", [self.searchBar isFirstResponder]);
if(![searchBar isFirstResponder]) {
// user tapped the 'clear' button
shouldBeginEditing = NO;
// do whatever I want to happen when the user clears the search...
}
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)bar {
// reset the shouldBeginEditing BOOL ivar to YES, but first take its value and use it to return it from the method call
BOOL boolToReturn = shouldBeginEditing;
shouldBeginEditing = YES;
return boolToReturn;
}
Basically, that's it.
Best
UIButton doesn't work when the searchController is active?
I just found an solution. For those who are having problem:
I was adding the Target this way
let button: UIButton = {
let button = UIButton(type: .custom)
button.setTitle("See all", for: .normal)
button.setImage(UIImage(systemName: "chevron.right", withConfiguration: buttonConfig), for: .normal)
button.addTarget(self, action: #selector(myFunc), for: .touchUpInside)
return button
}()
Removing the addTarget, and adding it on the Init of the class fixes the Problem.
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(button.addTarget)
button.addTarget(self, action: #selector(myFunc), for: .touchUpInside)
}
I Don't know why, but it works. lol
How to make keyboard dismiss when I press out of searchbar on Swift?
try this :
self.mySearchController.searchBar.endEditing(true)
replace mySearchController with your created controller name..
If you did not create it programmatically but instead you just dragged a search bar from library then IBoutlet your searchable to your class and reference it as:
self.mySearchBar.endEditing(true)
Don't display the UISearchController table until the search button is tapped
The empty table view you are seeing is from your search results controller, which is "immediately" displayed by UISearchController "when the user enters text in the search bar". (source)
Hiding the table view in your search results controller until you are ready to show it would seem to be the easiest solution. But as you discovered, upon displaying the search results controller, UISearchController sets the value of the isHidden
property on the root view to false
. In my debugging session, UISearchController behaved this way every time the search bar began editing or the search text changed, by calling a private method named _updateVisibilityOfSearchResultsForSearchBar:
.
You can work around that behaviour by adding the table view in the search results controller as a subview of the root view (and then hiding or showing the table view as necessary), or by adjusting the value of the alpha
property for the root view (which, unlike isHidden
, can be animated).
Make keyboard disappear when clicking outside of Search Bar - SWIFT
You can use this extension.
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard() {
view.endEditing(true)
}
}
Usage. In your viewController:
override func viewDidLoad() {
super.viewDidLoad()
hideKeyboardWhenTappedAround()
}
UISearchBar in a UICollectionView disappears when using UISearchDisplayController
I ended up implementing UISearchDisplayController
on my own. Here's my code.
ZBNSearchDisplayController.h
@protocol ZBNSearchDisplayDelegate;
@interface ZBNSearchDisplayController : NSObject<UISearchBarDelegate>
- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController;
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
@property(nonatomic,assign) id<ZBNSearchDisplayDelegate> delegate;
@property(nonatomic, getter = isActive) BOOL active;
@property(nonatomic, readonly) UISearchBar *searchBar;
@property(nonatomic, readonly) UIViewController *searchContentsController;
@property(nonatomic, readonly) UITableView *searchResultsTableView;
@property(nonatomic, assign) id<UITableViewDataSource> searchResultsDataSource;
@property(nonatomic, assign) id<UITableViewDelegate> searchResultsDelegate;
@end
@protocol ZBNSearchDisplayDelegate <NSObject>
@optional
- (void)searchDisplayControllerWillBeginSearch:(ZBNSearchDisplayController *)controller;
- (void)searchDisplayControllerDidBeginSearch:(ZBNSearchDisplayController *)controller;
- (void)searchDisplayControllerWillEndSearch:(ZBNSearchDisplayController *)controller;
- (void)searchDisplayControllerDidEndSearch:(ZBNSearchDisplayController *)controller;
- (void)textDidChange:(NSString *)searchText;
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope;
@end
ZBNSearchDisplayController.m
#import "ZBNSearchDisplayController.h"
@implementation ZBNSearchDisplayController
- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController {
self = [super init];
if (self) {
_searchBar = searchBar;
_searchBar.delegate = self;
_searchContentsController = viewController;
CGFloat y = 64.0f;
CGFloat height = _searchContentsController.view.frame.size.height - y;
_searchResultsTableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0f, y, _searchContentsController.view.frame.size.width, height)];
_searchResultsTableView.scrollsToTop = NO;
}
return self;
}
- (void)setSearchResultsDataSource:(id<UITableViewDataSource>)searchResultsDataSource {
_searchResultsTableView.dataSource = searchResultsDataSource;
}
- (void)setSearchResultsDelegate:(id<UITableViewDelegate>)searchResultsDelegate {
_searchResultsTableView.delegate = searchResultsDelegate;
}
- (void)setActive:(BOOL)visible animated:(BOOL)animated {
if (!visible) {
[_searchBar resignFirstResponder];
_searchBar.text = nil;
_searchBar.showsCancelButton = NO;
}
if (visible && [self.delegate respondsToSelector:@selector(searchDisplayControllerWillBeginSearch:)]) {
[self.delegate searchDisplayControllerWillBeginSearch:self];
} else if (!visible && [self.delegate respondsToSelector:@selector(searchDisplayControllerWillEndSearch:)]) {
[self.delegate searchDisplayControllerWillEndSearch:self];
}
[_searchContentsController.navigationController setNavigationBarHidden:visible animated:YES];
float alpha = 0;
if (visible) {
[_searchContentsController.view addSubview:_searchResultsTableView];
alpha = 1.0;
}
if ([_searchContentsController.view respondsToSelector:@selector(scrollEnabled)]) {
((UIScrollView *)_searchContentsController.view).scrollEnabled = !visible;
}
if (animated) {
[UIView animateWithDuration:0.2 animations:^{
_searchResultsTableView.alpha = alpha;
} completion:^(BOOL finished) {
self.active = visible;
}];
} else {
_searchResultsTableView.alpha = alpha;
}
}
#pragma mark - UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope {
if ([self.delegate respondsToSelector:@selector(searchBar:selectedScopeButtonIndexDidChange:)]) {
[self.delegate searchBar:searchBar selectedScopeButtonIndexDidChange:selectedScope];
}
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if ([self.delegate respondsToSelector:@selector(textDidChange:)]) {
[self.delegate textDidChange:searchText];
}
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:YES animated:YES];
[self setActive:YES animated:YES];
[_searchResultsTableView reloadData];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[_searchResultsTableView reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self setActive:NO animated:YES];
[self.searchResultsTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
}
@end
Make Cancel button in search bar active after search button tapped
In my experience if you do searchBar.endEditing(true)
then the cancel button is disabled, try adding this after that to see if its work, im also using it in my project:
func enableCancelButton (searchBar : UISearchBar) {
for view1 in searchBar.subviews {
for view2 in view1.subviews {
if view2.isKindOfClass(UIButton) {
let button = view2 as! UIButton
button.enabled = true
button.userInteractionEnabled = true
}
}
}
}
Related Topics
My Uiviews Muck-Up When I Combine Uipangesturerecognizer and Autolayout
Use More Than One Firebase Database in Single App - Swift
How to Retrieve Image Stored in Firebase to Show It in View Image View
Get Latitude and Longitude Center of Google Map
Libmobilegestalt Mobilegestalt.C:890: Mgisdeviceoneoftype Is Not Supported on This Platform
Swift Lazy and Optional Properties
Getting Error Ambiguous Use of Tableview(_:Numberofrowsinsection:)
Swift, Parse.Com: How to Pass Data from Query
Cmpedometer Querypedometerdatafromdate Returns Error 103
Turning on Thread Sanitizer Results in Signal Sigabrt
Caching Images in Collectionviewcell in Swift
iOS Healthkit How to Save Heart Rate (Bpm) Values? Swift
Get Current Song Playing in Spotify on Iphone
Uitapgesturerecognizer Sender Is the Gesture, Not the UI Object
App Groups Forsecurityapplicationgroupidentifier Returns Nil