UISearchDisplayController not displaying keyboard when text area touched - objective-c

I have a UITableView in a controller that is nested under a UITabBar.
The interaction is all wired up in Interface Builder so far, nothing done programmatically in terms of view switching.
I've added a UISearchDisplayController as the header of my UITableView. It displays fine, and when I tap on the text entry area, the cancel button appears and the black overlay flies in.
However, the keyboard never appears and when tapping the cancel button, the overlay flies out and the cancel button disappears, but the text entry area keeps focus and the caret stays flashing there, so I cannot tap there again to re-display the search results.
So essentially I have two problems:
Keyboard not appearing when starting to edit text on UISearchBar from UISearchDisplayController
UISearchBar not loosing focus when cancel button is tapped.
What am I doing wrong?

The .xib file that had my tab bar in it contained a UIWindow.
This lead to all sorts of craziness and in the end I gave up on trying to do this with interface builder, and resorted to constructing the UITabBar in code, thereby not creating a second UIWindow.
This resolved the problems and the UISearchDisplayController behaved correctly.

check this method in UISearchBarDelegate:
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar;
Try to see if this is getting called and do keyboard-related removal in here. If not, try making another UISearchDisplayController. (I actually never use the default viewController's one). Also, make sure the delegate is correctly set.

Related

Using tap gesture to dismiss keyboard, rest of screen no longer works

I have a UITableViewController that contains a UISearchBar in one of its cells. Following examples here, I put a addGestureRecognizer in my viewDidLoad to capture taps outside the searchBar and calls resignFirstResponder on the search bar so the keyboard is dismissed.
However, this seems to be trapping all taps, the other items in the tableView no longer respond.
This is odd, because I have the identical code (cut and pasted) in another screen, a UIViewController, and it works fine there. The user can continue clicking on other objects just fine.
Any ideas? I suspect this is a simple view hierarchy issue?
Ahhh, it seems the first version I wrote shouldn't work either. The key is to enable the tab gesture only when the searchBar is entered, and then disable it again when you exit. This question has all the code:
Cancel out of UISearchBar when user taps on view

Having trouble moving an UITextView in a UIScrollView when it's the first responder

I have a view controller that is basically a form with multiple UITextFields and UITextView, embedded in a UIScrollView. When an UITextField becomes first responder, the scroll view automatically move to the focused field, which is believe is the behaviour explained in the first answer in this topic :
Disable UIScrollView scrolling when UITextField becomes first responder
This does not happen when the first responder is an UITextView though, and I'm not sure why and how I should fix it.
The second problem is that when the keyboard is shown, the scroll view does not scroll if the UITextView is not in view (because it's hidden by the newly shown keyboard). I implemented the code of Apple's documentation on how to manage the keyboard :
http://developer.apple.com/library/ios/#DOCUMENTATION/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
And added another activeField variable named activeView for textViews (initialized in the beginEditing of TextView, set to nil in endEditing, and scrollToVisible according to it's frame when the keyboard is shown). The problem here is that the beginEditing in UITextView is called after the keyboardWasShown, so the activeView is not initialized and thus does not scroll. For some reason, for UITextFields the beginEditing is called before, which is the intended behaviour.
How can I scroll to an UITextView and it's the first responder, and how can I move to it when the keyboard is shown and hide it?
To scroll to show anything in a UIScrollView do
scrollRectToVisible:/*frame of object you want to show*/ animated:YES
Subscribe to UITextViewTextDidBeginEditingNotification and call the above method when you get it.

How to suppress virtual Keyboard slide-in animation?

I've got a problem with creating a modal search view that emulates the behaviour of that of the Weather app. Specifically, there are two animations, that are bothering me and introduce unneeded 0.2 s delays:
When the modal view becomes visible, I give focus to the UISearchDisplayController.searchBar by caling becomeFirstResponder in viewDidAppear. However, the keyboard is not visible, when the modal view has slid in, but needs another 0.2s to slide in after the animation of tehe modal view transition is complete. Moving the call to another callback like viewWillAppear or viewDidLoad did no good, the keyboard won't show up in the first place.
When the user touches cancel, there is another animation taking place, before the delegate's searchDisplayControllerDidEndSearch method is called, expanding the search text field and "melting" away the button. Again, this animation is unneded as the modal view is supposed to transition out when the button is touched.
Additionally, when I dismiss and re-present the same view, not only does the keyboard slide in after the transition, but the cancel button does the same (luckily simultaneously).
I am aware of a similar problem described here: Keyboard Animation Issues When Calling becomeFirstResponder within a Modal View Controller.
However, it seems like the behaviour of the search bar is sligtly differet then that of text field. I could not reproduce the steps described by that author to make the keyboard visible by calling becomeFirstResponder in viewDidLoad.
Regards,
Chris
I think I found your answer. When you add a search bar using the interface builder, you can do it two ways: "Search bar" and "Search bar and Search Display Controller".
I was using the second and was having the very same problem you described. I could only invoke the keyboard (using becomeFirstResponder) on "viewDidAppear". But if you do it adding just the search bar it works. Now I can call becomeFirstResponder on "viewDidLoad" and the keyboard appears together with the view itself.
I means a little more work, but really not much. You have to set your controller to be the delegate of the search bar. I added a list view for the results and made my controller become its delegate and its datasource.

Dismiss a number pad-style keyboard without adding Done key

There is no Done button on a Number Pad-type keyboard. I don't want to add a custom Done button, but how do I dismiss the keyboard?
You could add a UINavigationBar/UIToolBar with a done button(a UIBarButtonItem), and make the textField/textView resignFirstResponder on the done button's action.
You can add the UINavigationBar/UIToolBar as inputAccessoryView of textField/textView.
textField.inputAccessoryView = aNavBarWithDoneButton;
Edit: Availability iOS (3.2 and later)
The simplest solution is to add a new button somewhere in your UI that calls resignFirstResponder on your UITextField (or whatever) when tapped. Putting this in a toolbar is problematic on iPhone because toolbars are typically at the bottom of the screen and obscured by the keyboard.
A slightly more complex solution is to put an invisible UIView behind all of your other tappable UI elements. Any taps not handled by your existing UI will go to this new view, which can call resignFirstResponder on your text field.
If neither of these sound appealing, perhaps you should expand your question to include the type of behavior you want.

How To: hide keyboard when UITextView is out of view?

I've put some UITextViews in a UITableView(Controller) with custom cells, and I'm running into a problem. The user can hit the "Edit" button up in the navbar to set the table into editing mode - each custom cell has its own way of enabling its individual UITextViews for text entry. That works fine.
The problem I'm having is that if focus is on a text view that gets scrolled out of view when the user hits "Done", the keyboard remains and the textview remains in edit mode. This doesn't happen if the textview is in view. More specifically - the cell i'm looking at is at the top of the screen and will act funny if it's scrolled above the iPhone screen. I don't seem to have the same problem when the textview at the bottom of the table gets scrolled out.
I've done just about every single permutation I could think of to get the view to resign first responder, but it appears to me that the hidden textview doesn't get/send any messages (even any delegate methods) until it is back on to the screen OR some other text view gets focus.
What am I missing?
After working on this for the better part of a full day, this is what I learned:
You can't actually access
out-of-view cells in UITableView. I
guess that makes sense, though
frustrating in my situation
No amount of redrawing or trying to
manually resign first responder is
going to help, even when you point
to a specific cell in a specific
row.
setEditing: animated: (called when you hit the "Done" button) isn't the only thing going on
I'm going to guess that the reason the UITextView remains in edit mode is because the cached version of the cell is in edit mode and cached cells/data aren't called by these various table methods (like setEditing:animated:)
This is the solution I found: (at UISearchBar and resignFirstResponder):
* calling [self.tableView endEditing:YES] causes all views to resign first responder, which means my UITextView is no longer selected. I'm not sure why it works this way, but appears setEditing: is sent to each cell & redrawn accordingly.