keep keyboard when searchDisplayControllerWillEndSearch is invoked - ios

With help from other posts on this site, I have managed to open up search display controller with keyboard when a button is tapped. I can see the underlying UIView is dimmed too.
What I now want to do is, not have the keyboard dismissed when the user taps outside the search bar. Currently, the keyboard gets dismissed and searchDisplayControllerWillEndSearch is invoked.
I have tried combinations of the following but none worked.
self.searchDisplayController.searchBar.hidden = NO;
[self.searchDisplayController.searchBar setShowsCancelButton:YES animated:YES];
[self.searchDisplayController setActive: YES animated: YES];
[self.searchDisplayController.searchBar becomeFirstResponder]
Can anyone please suggest any ideas?

I haven't been able to try this, but I think it should work
Declare something as searchbar delegate;
#interface YourViewController : UIViewController <UISearchBarDelegate>
Then, somewhere in YourViewController.m, set:
- (BOOL) searchBarShouldEndEditing:(UISearchBar *)searchBar {
return NO;
}
You can set it to return something dynamic, for instance if we only wanted to allow it to stop editing if there isn't any text, we could do this.
- (BOOL) searchBarShouldEndEditing:(UISearchBar *)searchBar {
return (searchbar.text.length > 0) ? YES : NO;
}
This way, if the user has started typing, or any text is in the search bar, it won't resign.
Let me know if this works.

Related

Hide Keyboard on clear click in UISearchBar and not backspace to empty text

I cant seem to find this answer for the manually clearing the UISearchBar with a backspace, only with a cancel button click. The code below hides the keyboard when the clear button is clicked, but so does the backspace to an empty UISearchBar. Id like to leave the keyboard open in that scenario since someone might be typing something else.
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
[self filterData: text];
if(text.length == 0)
{
[searchBar performSelector:#selector(resignFirstResponder) withObject:nil afterDelay:.1];
}
}
Your code includes if(text.length == 0) and that means that when the size of the input becomes zero, keyboard is dismissed. However the actual piece should be as follows:
- (BOOL) searchBarCancelButtonClicked:(UISearchBar *)searchBar{
[searchBar resignFirstResponder];
return YES;
}
My best try on such an issue is to do as suggested here BUT IT DOES NOT WORK WHEN YOU CLICK CLEAR BUTTON :( but I thought it might help you though:
https://stackoverflow.com/a/16957073/1465756
Add a tap gesture on your whole view:
- (void)viewDidLoad
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
and dismissKeyboard when the view is tapped:
- (void) dismissKeyboard
{
[self.searchBar resignFirstResponder];
}
I understand you want to dismiss the keyboard when the user hits Cancel, and you also want to dismiss when the user hits the clear (x) button.
You do not need to implement searchBar:textDidChange:.
To detect cancellation, implement searchBarCancelButtonClicked:. Here you can trigger resignFirstResponder.
To detect clear, adopt UITextFieldDelegate and implement textFieldShouldClear:. This will be called after the user taps clear, but before the clear occurs. Return YES to allow the clear to occur. You may dismiss the keyboard before returning.

When assigning focus via becomeFirstResponder to UISearchController's UISearchBar, the keyboard does not appear

I've spent quite a bit of time searching online and talking to other developers about this issue to no avail. The exact issue is described in this SO post (Focus on the UISearchBar but the keyboard not appear), although it's many years old.
I recently switched from using the deprecated UISearchDisplayController and UISearchBar in IB, and switched over to UISearchController via the code for iOS8.
The problem I'm getting however, is that focus is assigned correctly (you can tell because the cancel button animates to the right of the search bar after the view loads), however the keyboard does not show up.
Here's the code that I have.
.h
#property (nonatomic, strong) UISearchController *searchController;
.m
- (void)viewDidLoad {
[super viewDidLoad];
...
[self initializeSearchController];
....
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.searchController setActive:YES];
[self.searchController.searchBar becomeFirstResponder];
}
- (void)initializeSearchController {
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.delegate = self;
self.searchController.searchBar.delegate = self;
[self.searchController.searchBar sizeToFit];
[self.tableView setTableHeaderView:self.searchController.searchBar];
self.definesPresentationContext = YES;
}
The things I've tried so far.
I've tried calling becomeFirstResponder on a 0.2 second delay, as suggested in another SO post.
I've set a breakpoint in viewDidAppear, and verified that both self.searchController and self.searchController.searchBar are both valid objects, neither nil.
I've tried conforming to the UISearchControllerDelegate and using the following snippet of code
here:
- (void)didPresentSearchController:(UISearchController *)searchController {
//no matter what code I put in here to becomeFirstResponder, it doesn't
//matter because this is never called, despite setting the
//self.searchController.delegate = self AND
//self.searchController.searchBar.delegate = self.
}
I've created a new view from scratch in storyboards, and segued to that one instead, to make sure I didn't have some old searchBar remnant in my view. This did not work either.
I've only tested this on a real device (iPhone 6), and it's not a simulator issue of not showing the keyboard.
I'm out of ideas, and I've seen every question and answer related to this one the web. Nothing is working.
To clarify again what's going on, the searchBar correctly becomes the first responder, the cancel button to the right of it animates onscreen proving this, but the keyboard does not appear and the cursor does not blink in the searchBar.
Your code looks ok. What you are describing isn't normal behaviour.
The first thing you can do is to create a new project with just the UISearchController functionality and see how it goes. You can edit your question with it so we'll have a better view.
There's a good example on how to implement UISearchController here: Sample-UISearchController
Adding:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.searchController.searchBar becomeFirstResponder];
}
to MasterViewController_TableResults.m gave the expected results and the keyboard popped up on launch on an iPad & iPhone with iOS 8.3.
You can go over that project and see what you did differently,
Edit:
Apparently if [self.searchController setActive:YES] is called before becomeFirstResponder the keyboard won't show. I wonder if that's a bug or not.
Had the same annoying issue.
You would think that by setting the SearchController as active would both present the the search controller and the keyboard. Unfortunately, it only does the first part.
My solution
in viewDidAppear make the Search Controller active:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
resultSearchController.active = true
}
once it is active, in didPresentSearchController make as first responder
func didPresentSearchController(searchController: UISearchController) {
searchController.searchBar.becomeFirstResponder()
}
Swift 3.0 (iOS 10) working solution:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
searchController.isActive = true
DispatchQueue.main.async { [unowned self] in
self.searchController.searchBar.becomeFirstResponder()
}
}
On iOS 9 I've found its sufficient to delay becomeFirstResponder() to the next run loop:
func focusSearchField() {
searchController?.active = true
// skipping to the next run loop is required, otherwise the keyboard does not appear
dispatch_async(dispatch_get_main_queue(), { [weak self] in
self?.searchController?.searchBar.becomeFirstResponder()
})
}
Working Solution:-
Don't use [self.searchController setActive:YES] before becomeFirstResponder.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
// [self.searchController setActive:YES];
[self.searchController.searchBar becomeFirstResponder];
});
});
}
In iOS 10, I had to run the code in delegate method on main thread. First I set the active to YES in viewDidAppear,
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self.searchController setActive:YES];
}
and then in the delegate method:
- (void)didPresentSearchController:(UISearchController *)searchController
{
dispatch_async(dispatch_get_main_queue(), ^{
[searchController.searchBar becomeFirstResponder];
});
}
The solution that will work is as follows :
1.Override ViewDidLayoutSubviews in the view controller in which you are showing UISearchController
2.Override ViewDidLayoutSubviews and inside it make search bar first responder.
Tested it on iOS > 9.0
Caution : Put a null check before making it First responder as follows
if((searchController != null)&&(searchController.SearchBar != null))
searchController.SearchBar.BecomeFirstResponder();
This is because ViewDidLayoutSubviews also gets called when cancel button is pressed.
This worked for me in Xamarin.
I had trouble with an UISearchBar not displaying the keyboard when doing
[searchBar becomeFirstResponder];
By searching on the net, i found this thread on the Apple developer website
that helped me to discover that the keyboard won't open if you don't have a keyWindow.
The application i work on do something like this :
Window A (KeyWindow)
do some things
open Window B (KeyWindow)
do some things
close Window B (resign KeyWindow)
I just had to do
[[[[UIApplication sharedApplication] windows] firstObject] makeKeyWindow];
after the resigning of window B and no more trouble with the keyboard.
This might also be related to Simulator Settings. Just disable Hardware -> Keyboard -> "Connect Hardware Keyboard" .
For further details: UISearchBar not showing keyboard when tapped
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.searchController setActive:YES];
}
//and then in the delegate method:
- (void)didPresentSearchController:(UISearchController *)searchController
{
dispatch_async(dispatch_get_main_queue(), ^{
[searchController.searchBar becomeFirstResponder];
});
}
//The above works for me in addition to this I had to add:
-(void)viewWillDisappear:(BOOL)animated {
[searchController setActive:NO];
}

UISearch Bar Not Being Updated By Keyboard Input

I have a ViewController with a subview that contains a UISearchBar. When I click on the search bar the keyboard appears and I am able to close it using the cancel button. The problem seems to be that it isn't accepting any of the input when a user clicks on the keyboard buttons.
#pragma mark -
#pragma mark SEARCH METHODS
#pragma mark -
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
self.mainSearchBar.showsCancelButton = YES;
return YES;
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[self.mainSearchBar resignFirstResponder];
self.mainSearchBar.showsCancelButton = NO;
self.mainSearchBar.text = #"";
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self.mainSearchBar resignFirstResponder];
}
Has anyone had this issue before or know how to fix it?
** UPDATE *****
It turns out the Siri will work when trying to edit the UISearchBar. Still no luck with the keyboard input though. I think it has something to do with the fact that the UISearchBar is situated on a UIView that is then added as a subview. Not sure how to fix it though.
** UPDATE 2 *****
Moved the search box to the main UIView and I am still getting the same error. I am wondering if it is now related to the Navigation Controller.
Make sure that the app delegate has a [self.window makeKeyAndVisible]. Hopefully it will solve your problem.
Check whether you have added a UISearchBarDelegate in your viewController's .h file.
Try this code also:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
NSLog(#"%#",searchText);
}
This has to be related to how the SearchBar is rendered in relation to the ViewController's view. Why are you making the SearchBar a subview of another view rather than a subview of the ViewController's view?
Problem solved, the answer was found on a previous thread Keyboard and cursor show, but I can't type inside UITextFields and UITextViews
It turns out that in IOS6 the Visible at Launch check needs to be clicked on the options.

Hiding keyboard iphone sdk?

I have a UISearchBar. I want the the keyboard to go away as soon as user hits search...i did try resignFirstResponder but that didn't work. any help would be appreciated
- (void)viewDidLoad {
[super viewDidLoad];
self.title = NSLocalizedString(#"Songs", #"Search for songs");
NSMutableArray *array = [[NSArray alloc]initWithObjects: #"Book_1", #"Book 2", #"Book _ 4", nil];
self.booksArray = array;
[array release];
search.delegate=self;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
thanks
TC
Please make sure of following things.(I hope you are talking about search Button of keyboard.)
You have connected your IBOutlet of searchBar with its variable search.
You are not de-referring search variable anywhere in your code(reassigning it).
Your - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar method is in same viewcontroller as searchBar is in.
Please NSLog(#"Search Bar Instace : %#",search); in viewDidLoad method and searchBarSearchButtonClicked and verify that both instances are same if not then you are search is getting reassigned somewhere in code.
Just after [searchBar resignFirstResponder]; NSLog(#"isFirstResponder : %d",[searchbar isFirstResponder]); and NSLog(#"Next Responder : %#",[searchBar nextResponder]);
Is - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
method is being called when you tap search Button of keyboard? Make sure there are no keyboard responder(like textField,textView or other searchBar) is added behind your searchBar may be unintentionally. Please check it through xib also.
Thanks,
It should work by implementing the respond methods at the delegate object:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
Reference: http://www.iphonedevsdk.com/forum/iphone-sdk-development/7148-problem-uisearchbar-navigation-controller.html#post59467

Modal Dialog Does Not Dismiss Keyboard

I am running into an issue where the keyboard does not get dismissed when leaving a UITextField or UITextView in a UIModalPresentationFormSheet. In addition, I've created a large button to serve as the view's background so if the user taps outside the fields it gets triggered. I am using the same code in a regular view controller, and it works as expected. In the modal view controller it does nothing. Any suggestions would be appreciated.
- (BOOL)textFieldShouldReturn:(id)sender {
[titleTextField resignFirstResponder];
return YES;
}
- (BOOL)textViewShouldReturn:(id)sender {
[synopsisTextView resignFirstResponder];
return YES;
}
- (IBAction)textFieldDoneEditing:(id)sender {
[sender resignFirstResponder];
}
- (IBAction)textViewDoneEditing:(id)sender {
[sender resignFirstResponder];
}
- (IBAction)backgroundClick:(id)sender {
[titleTextField resignFirstResponder];
[synopsisTextView resignFirstResponder];
}
Overriding disablesAutomaticKeyboardDismissal to return NO as below fixed the same problem of mine. You should put this code to your view controller, from which you initiate the keyboard:
- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}
Also, check this SO question if you want to get a detailed explanation.
For those having trouble with UINavigationController, I think there is a better solution than a category on UIViewController. We should change the behavior of UINavigationController to ask its topViewController (in my opinion, this is how all ViewController containers should handle this).
#implementation UINavigationController (DelegateAutomaticDismissKeyboard)
- (BOOL)disablesAutomaticKeyboardDismissal {
return [self.topViewController disablesAutomaticKeyboardDismissal];
}
If you're presenting a modal view with presentation style "form sheet", Apple apparently does not dismiss the keyboard, thinking that they don't want the keyboard to jump in and out where a user will be doing a lot of editing (i.e. "forms"). The fix would be to change presentation style or live with it.
If you implement the UITextFieldDelegate protocol you can inadvertently cause this behavior if you do text validation. If your validation codes returns false from textFieldShouldEndEditing when the text is invalid, the field can't relinquish it's firstResponder status and the keyboard will remain on screen in the next view.
More details at UITextField's keyboard won't dismiss. No, really
I solved this by resizing a UIModalPresentationPageSheet. See my answer here.
The disablesAutomaticKeyboardDismissal refused to work for me on iOS 7.
But... I managed to solve this issue by simply disabling the UITextFields on the screen.
My solution is described here.
This workaround even works on Modal UIViewControllers.
Yeah... it surprised me aswell !!
i have also facing same problem and also done everything but not thing works then i start thinking and get some result.
but this answer for those who want to dismiss keyboard on textfield click and then open pop up.
so all you need to call text field delegate
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField == self.myTxtFieldName{
self.view.endEditing(true) // keyboard hide code
// here you can call your model or pop up code and keyboard will dismiss and your pop up open
return false
}
return true
}
Sorry if this is not working for you
if there is other answer then please edit it
Thank you

Resources