iOS Keyboard Active But Invisible When Uisearchbar Is Tapped

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



Leave a reply



Submit