How to get a notification for a UISearchBar hiding? - iphone

Is there any way to recieve a notification when a UISearchBar is finished (e.g Cancel button clicked or otherwise lost focus.
We don't have access to the UITextField inside, or I could attach an observer to it.
I can be notified when the keyboardWillHide, but I've got another text field, so it could be either one. And it becomes inactive before the keyboard hides, so no love.
I have access to the UISearchBarDelegate and UISearchDisplayController(Delegate).
Can anyone tell me where to look? Is there a master list of all notifications to choose from?

These methods should do it for you:
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar; // called when text ends editing
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar; // called when keyboard search button pressed
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar; // called when bookmark button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *) searchBar; // called when cancel button pressed
These are all UISearchBarDelegate delegate methods. By rule, delegate methods are more closely bound than adding observers for notifications. This was mentioned in one of Stanford University's iPhone videos. Though i myself use notifications generously and have found no problem with them.

In general, if there is not a Notifications section in the Apple docs for a class then there are no notifications that a publicly available for said class.
I would go with Chintan's suggestion of using the delegate.

Related

removing keyboard from Screen without calling resignFirstResponder

I have a custom View (NotifyView) added on UIWindow with a dismiss button(which remove it from UIWindow).
This view is added when a PUSH notification comes in didReceiveRemoteNotification
there are several cases when I could be on any screen, and my keyboard is UP via UITextfield/UITextview.
At this stage if a push comes, the NotifyView is added on UIWindow behind the keyboard.
I want to resign the keyboard once the PUSH is received so for that I could:
post a Notification with NSNotificaitonCenter to resign all textfields/textviews (if anyone is firstResponder). For this I have to keep active pointer to the currently active textfield/textview in all controllers.
make a variable in AppDelegate and assign the active textfields/textviews to it and on PUSH, and resignFirstResponder of those on PUSH.
Both of the solutions would require making changes to all controller's code and I am looking for something more generic like:
could there be any way through which I could simply remove the Keyboard from the screen on receiving PUSH
or I could fetch the current firstResponder of the application and resign it explicitly.
these could be generic solutions.
It would be really helpful if someone could facilitate this thought process or someone have any immediate solution for this case.
You can use the method below
[[[UIApplication sharedApplication] keyWindow] endEditing:YES]
Try this one , for me it works fine
[yourView endEditing:YES]
The problem it is, when you want to give back the focus.
I have implemented as listening each textfield and caching which is the latest. Than resign only that one ( in push ) after that restore state, require focus for that.
Try this in delegate method...
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[self.view endEditing:YES]; // added this in for case when keyboard was already on screen
[self editStartDate:textField];
return NO;
}

How can I make an unknown UITextField resign first responder?

My view has two UITextFields and a UISwitch. If a user is edits a textField, and then immediately touches the switch (without pressing return), the text is left as they typed it, without AutoCorrect.
If I know which textField they were typing in, I can force the autocorrect to complete by calling [textField resignFirstResponder]. But the user could be typing in either textField, so I don't know which one to call.
How can I get around this? Is there a way of detecting which textField was being used? Or something simpler I haven't thought of?
One lovely way of doing this without having to keep track of which field is active:
// This causes the current responder (eg. an input field) to resignFirstResponder and
[self.endEditing:YES];
Replace [self.view endEditing:YES] with the below one...
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder) to:nil from:nil forEvent:nil];
The uitextfielddelegate methods are called for the textfield on which the editing is in progress. So that way you needn't be facing the problem of detecting which text field is being edited.
So implement the uitextfielddelegate methods and assign the delegate of the text field to the class where you implement the methods and handle the responses in them.
The methods which you should be interested in are:
textFieldDidEndEditing:
Tells the delegate that editing stopped for the specified text field.
- (void)textFieldDidEndEditing:(UITextField *)textField
Parameters
textField
The text field for which editing ended.
Discussion
This method is called after the text field resigns its first responder status. You can use this method to update your delegate’s state information. For example, you might use this method to hide overlay views that should be visible only while editing.
Implementation of this method by the delegate is optional.
Availability
Available in iOS 2.0 and later.
Declared In
UITextField.h
You may keep track yourself which one is the current one, by using the textFieldDidBeginEditing delegate.

becomeFirstResponder without hiding Keyboard

I have a view that supports copy and shows the edit menu using the following code:
if ([self becomeFirstResponder]) {
// bring up edit menu.
UIMenuController *theMenu = [UIMenuController sharedMenuController];
[theMenu setTargetRect:[self _textRect] inView:self];
[theMenu setMenuVisible:YES animated:YES];
}
The problem is, that when becomeFirstResponder gets called, the keyboard get's hidden. A good example of the correct behavior is in the SMS app. Double tap a message while the reply box is visible and the reply box looses focus, but the keyboard stays in place. Also, when the bubble is deselected, the reply box regains focus.
Unfortunately, Apple can do a lot of things that are not available to third-party apps.
I believe what you want is possible in iOS 3.2+ if you make the view that is to become the first responder accept keyboard input. You do that by having your view class adopt the UIKeyInput protocol:
A subclass of UIResponder can adopt this protocol to implement simple text entry. When instances of this subclass are the first responder, the system keyboard is displayed.
The protocol consists of 3 required methods that you have to implement. In your case, you would probably apply the inputs you receive in these methods to your text field and make it the first responder again. I haven't tried this but it should work.

Does UITextField consume touch events?

My view controller has UITextField object as a subview. The controller is set as target to handle the text field's UIControlEventTouchUpOutside event.
I'm trying to use this event handler for dismissing keyboard when the text field becomes first responder, but it seems to be never called. Delegate methods like textFieldShouldReturn work just fine.
Why the text field object doesn't send action message to the target? I tried this scheme for bunch of all touch events, but no luck.. Or do I have to subclass UITextField somehow to be able to catch this event?
Thanks in advance!
UITextField for sure responds to those event to handle cursor positioning and so on. It might not 'forward' those event to its parent. If you need to intercept those, you can subclass UITextEvent and catch those event yourself (of course do not forget to call [super blablabla] in order to keep the standard behavior.
Maybe It just doesn't respond the UIControlEventTouchUpOutside event. I am sure it will respond UIControlEventValueChanged event. I think you can put a transparent custom UIButtom as background view, and if any touchInSideUp in the UIButtom, you can dismissing keyboard as desired.
It responds to the same events as UIButton. Take a look in IB. Also you may consider using UITextFieldDelegate method
- (BOOL) textFieldShouldBeginEditing:(UITextField *)textField

UIAlertViewDelegate clickedButtonAtIndex: usefulness?

The UIAlertViewDelegate protocol defines two methods, alertView:clickedButtonAtIndex: and alertView:didDismissWithButtonIndex:, which seem to me to be identical in usefulness.
Why is there a clickedButtonAtIndex and a didDismissButtonWithIndex when they both do the same thing? I realize there is also a willDismissButtonWithIndex that happens before the alert view is dismissed, but is there any reason to use clickedButtonAtIndex instead of didDismissButtonWithIndex?
I found a more useful difference between the two:
When showing a UIAlertView, and the device goes to sleep, alertView:didDismissWithButtonAtIndex: gets called, even though the alert view is not actually dismissed. It is shown again once the device wakes up. alertView:clickedButtonAtIndex: is only called when the user clicks one of the buttons.
The alertView:clickedButtonAtIndex: is called when the user clicks a button on an alert view whereas the alertView:didDismissWithButtonIndex: is called after an alert view is dismissed from the screen. (See the UIAlertViewDelegate Protocol Reference.)
The difference is minimal but it allows you to do something before or after animation.
If the alert view disappears for any reason (including being covered by another UIAlertView, going to sleep, etc.), didDismissWithButtonAtIndex: is called. This can mean that the method can be called even without the user clicking on anything. This can lead to unexpected behaviour if you depend on this delegate callback to be called in response to the user actually clicking on a button. In this case clickedButtonAtIndex: is more useful.
I couldn't reproduce Ed's behaviour by locking my device with the alert view present on iOS 7.
However, the most important difference between alertView:clickedButtonAtIndex:, alertView:didDismissWithButtonIndex: and alertView:willDismissWithButtonIndex: is that the first method (clickedButtonAtIndex:) is only called when the user explicitly taps on a button on your alert view (hence 'clicked').
Is it possible that an alert view is dismissed without clicking on a button? Yes, you could programmatically hide an alert view using the UIAlertView method dismissWithClickedButtonIndex:animated:.
So, if you need some behavior to be always triggered upon the dismissal of the alert view—whether it was triggered by the user tapping on a button or triggered programmatically—then using the didDismissWithButtonIndex: and willDismissWithButtonIndex: makes more sense.