I'm looking at TVAnimationGestures from WWDC 2010, and in the TableVieWController.m, they override canBecomeFirstResponder:
- (BOOL)canBecomeFirstResponder {
return YES;
}
Is there a reason they do this? I don't see this method called anywhere. Thanks.
So you can mark your question as answered...
They are using an UIMenuController within the sample, and in order to receive messages from that controller to your controller, you must make your controller the first responder (and accept becoming first responder via canBecomeFirstResponder.
This method is called by the Cocoa framework and not typically application to see if a controller should become the first responder. While I haven't looked at that specific example, it probably allows the table to be editable.
I needed to override canBecomeFirstResponder in a custom UIView so I could use a custom InputView and InputAccessoryView.
Custom Views for Data Input
I had to do it this way because if I used a UITextField or UITextView, a hardware keyboard would subvert the more limited on-screen keyboard.
Related
I have UIView, that can contain one of two views. When I removeFromSuperview first view and addSubview second view I can still hear accessibiliyLabel of hidden view. And only in 1-2 seconds I can hear correct accessibiilityLabel.
I see that it is common situation when hidden state of view is changed, accessibility can be frustrated and still speak hidden views, and does not note visible views.
Also if in UITableViewCell UIButton is hidden and then hidden state changes to NO, VoiceOver ignores it like it is still hidden. Only manual implementation of UIAccessibilityContainer protocol for cell resolves mentioned problem
No Notifications can solve this issue. Even playing with accessibilityElementsHidden did not help. Struggling with this during several days
Please can you recommend is there any way to say Accessibility that hierarhy of views was changed
You can post a UIAccessibilityScreenChangedNotification or UIAccessibilityLayoutChanged to alert UIAccessibility that the view changed. Since you didn't post any code, I can only give you a generic example, e.g.:
UIAccessibilityPostnotification(UIAccessibilityLayoutChanged,accessibilityelement)
...where "accessibilityelement" would be a button or text field or other accessibility element that VoiceOver switches to next.
Reference: UIKIt Reference
Just ran into this myself with a third party side menu library and had to use accessibilityElementsHidden to fix it. I first tried leveraging the accessibilityViewIsModal property, but that only works on sibling views.
#pragma mark - IIViewDeckControllerDelegate
- (void)viewDeckController:(IIViewDeckController *)viewDeckController didOpenViewSide:(IIViewDeckSide)viewDeckSide animated:(BOOL)animated
{
if (viewDeckSide == IIViewDeckLeftSide) {
[self.topViewController.view endEditing:YES];
self.viewDeckController.leftController.view.accessibilityElementsHidden = NO;
}
}
- (void)viewDeckController:(IIViewDeckController *)viewDeckController didCloseViewSide:(IIViewDeckSide)viewDeckSide animated:(BOOL)animated
{
self.viewDeckController.leftController.view.accessibilityElementsHidden = YES;
}
any example for how to use this?
I can't understand the document.
This is only about a view controller presented using UIModalPresentationFormSheet. In that case, a text field resigning first responder will not cause the keyboard to be dismissed unless you override disablesAutomaticKeyboardDismissal to return NO.
The rest of the framework will call it at an undefined time before they need to know if the view controller in question disables automatic keyboard dismissal. Since your implementation of a UIViewController subclass (where you are meant to override it) should return either always YES or always NO, it doesn't matter when it's called.
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.
I want a UITextField to be sent the resignFirstResponder message if it is being edited and a user touches elsewhere on the screen. Since there are several text fields I need a way to programmatically determine which one is the first responder to send it the message. How can I do this? Is there some sort of global first responder object?
Thanks,
Jacob
The simplest way is to find the first responder and tell it to resignFirstResponder.
UITextField inherits from UIResponder so you can use isFirstResponder (which returns a BOOL) to query it.
if ([myTextField isFirstResponder]) {
// do stuff
}
Is there an iPhone equivalent for the NSResponder methods -selectNextKeyView or -nextValidKeyView from Mac OS X? I know about the -becomeFirstResponder method, but finding out which view to call that on is not very pretty when view hierarchies get more complicated.
There must be some kind of way to find this out as when I press tab when in the iPhone Simulator, focus does properly go to the next UITextField. This made me wonder what exactly happens when I press tab. Any ideas?
Update: This does exactly what I want, but _nextKeyResponder is private API, so a no-no. Is there any way to do a 'fake' tab key press without using private API?
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// Try to find next responder
UIView *nextResponder = (UIView *)[self.view _nextKeyResponder];
if (nextResponder) {
// Found next responder, so set it.
[nextResponder becomeFirstResponder];
[self.tableView scrollRectToVisible:[self.tableView convertRect:[nextResponder frame] fromView:nextResponder] animated:YES];
} else {
// Not found, so remove keyboard.
[textField resignFirstResponder];
}
return NO; // We do not want UITextField to insert line-breaks.
}
There is not a public iOS equivalent for NSResponder's -selectKeyView or -nextValidKeyView.
When the first responder is an instance of UITextField, pressing tab instantiates a private subclass of UIEvent which is passed to -[UIApplication sendEvent:], which in turn calls -[UIView _nextKeyResponder].
-[UIView _nextKeyResponder] doesn't work quite the way you think it does. It treats the key view chain as a loop, so your else block will never be reached. For the same reason, even if there was a public API for synthesizing keyboard events, you probably wouldn't want to use it.
Instead, you probably want something more like UIWebView's UIToolbar-based form input accessory. Its buttons can be enabled and disabled when appropriate, and its delegate handles the actual button press actions.
To implement such a delegate in a general way, however, it might be helpful to look at how -[UIView _nextKeyResponder] is implemented.
In the UITextField delegate -textFieldDidEndEditing:, switch between the various text fields (for example, by testing the text field's tag property).
When you match one text field, set another text field or other control to become the next responder.
I'm surprised nobody else appears to have solved this on iOS.
I devised a solution that handles both Tab and Shift+Tab to go forward and backward to any field you want on iOS, and doesn't use any private APIs.
Here is the write-up: http://weaklyreferenced.wordpress.com/2012/11/13/responding-to-the-tab-and-shift-tab-keys-on-ios-5-ios-6-with-an-external-keyboard/