I would like to be able to have another control become the first responder yet keep the keyboard showing to the user.
I found disablesAutomaticKeyboardDismissal in UIViewController and overrode it but it never get's called (iOS 5.0)
Is there a reason this method would not get called? Is there another way to keep the keyboard showing even though it's not required by the first responder?
Though it felt a bit like a hack what I did was make override canBecomeFirstResponder on UIView to return YES and then implement the UIKeyProtocol
https://developer.apple.com/library/IOS/documentation/UIKit/Reference/UIKeyInput_Protocol/Reference/Reference.html
But did nothing on key press. This way the keyboard stays open but the keys don't matter.
Related
I am getting this strange error in iOS 9 only:
[UIWindow endDisablingInterfaceAutorotationAnimated:] called on UITextEffectsWindow: ...without matching
-beginDisablingInterfaceAutorotation. Ignoring.
Anytime I dismiss the keyboard interactively by dragging down from within my collectionView. I don't get the error by dismissing the keyboard with a tap gesture or pressing enter. It is very frustrating. Even if I don't observe any keyboard notifications, I still get this error on this interactive keyboard dismissal. I wonder if anybody else has come across this error and found a solution. I have an inputAccessoryView consisting of a textView mounted on the keyboard.
I had the same problem on iOS9 but with a tableView. I implemented this along with self.tableView.keyboardDismissMode = .Interactive and it worked for me.
// Dismiss keyboard when scrolling
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
textView.resignFirstResponder()
}
Things to Check
It appears that several other SO users have had similar experiences under a variety of conditions. Check out this thread. Since there could be a lot of things happening that cause this problem you might want to review the thread provided to see if you can find a matching use-case. It's unclear how you are dismissing the keyboard but you might want to call something like this from a method or as a gesture recognizer (rather than a direct dismissal from a specific object):
UIApplication.sharedApplication().sendAction("resignFirstResponder", to: nil, from: nil, forEvent: nil)
From the thread provided, the nature of the issue in most cases was a duplicate call during presentation or dismissal of the view. I've also seen issues where I have a storyboard segue connected (or in some cases it was removed but the xml was still in the storyboard code view) and a code-based segue (performSegueWithIdentifier...) for the same animation (which causes two display/dismiss calls).
I'd look at the log to see what calls are being logged just before the error and then do a find in the log view to see if there is a redundant call. Again there could also be a redundancy in the behaviors/animations/layouts on the storyboard and calls made in the code.
UPDATE
The comments from the OP, reminded me that in some cases especially those involving calls during presentations/dismissals, I have seen instances where the only way to successfully have a developer function work is to wrap it into a dispatch_async call. There are some critical systems calls that appear to not work well if developer code is introduced during the same frames.
A concrete example is this call which is within willMoveToWindow. In this case I have a weakSelf reference to the view and simply review the newWindow for nil value (indicates the view is being dismissed) before calling my code.
So in this example if one removes the dispatch call, then the developer code would cause the entire app to crash. I'm guessing that the system transition calls (related to transposing to/from the window) may be conflicted with whatever the developer requests at that time.
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//the saved flag is true only when user hits the done button
if !(weakSelf!.saved) {
weakSelf?.completeNotes(nil)
}
})
I encountered this issue and it messes up my view. This is how I solve it.
I was having a viewController being presented on textFieldShouldBeginEditing. In the viewController, a textField was set to becomeFirstResponder in viewDidLoad.
The solution for me is to move the becomeFirstResponder to viewDidAppear.
In one of my apps, when I try to edit (type some text) UITextField, UITextView or any other 'text-able' UIControl the cursor just blinks but no characters are typed in except BACKSPACE (possible only when I have some initial text in it), RETURN and switching character types. This goes to all controls across whole application.
Summary:
It happens only from iOS 6.0 (does not occur on iOS 5.x, 4.x neither Simulator or real device)
All delegate methods are fired (shouldBeginEditing: didBeginEditing:) except shouldChangeCharactersInRange:
isFirstResponder flag is behaving set correctly (shouldBeginEditing: logs NO, while didBeginEditing: logs YES correctly). It is also tested using logs that THE firstResponder IS the one already edited.
It repairs itself after any UIAlertView is presented to the user and dismissed. It doesn't matter if this alert is shown on the same screen (UIViewController view) or any other.
I have no idea how to even approach or debug this.
Where should I look for hints? Any experts of tracking responder chain related issues etc.?
How can I track down the UIAlertView's effect on the issue?
Depending on your implementation it's either the makeKeyAndVisible method of the UIWindow class that you forgot to call inside the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method of the application delegate or corresponding Visible at Launch flag in your main interface xib file.
Cheers... :)
in my case, there is a 'visible at launch' on the main window, it was unchecked, which works on iOS5 only, needs to check it to make it working on iOS6.
In my situation I had an activity indicator that would pop up over the main window during periods of background activity. In this case the activity indicator view had its own window that was set to UIWindowLevelAlert. I was inadvertently calling makeKeyAndVisible on this window. Later on I would call resignKeyWindow. This used to work on iOS 4 and 5 but no longer worked in iOS 6. I discovered that this was not technically necessary as simply using window.hidden = Y/N worked just as well.
In my case I moved becomeFirstResponder for my UITextField from ViewDidLoad to ViewDidAppear and this solved my problem.
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.
Alright, so here is what I am trying to do. I have a UITextField. When I single tap it, I want to call one of my methods. When I double tap (tap it twice with 1 finger) it, I want to edit the text field (as though I had single tapped it on a normal UITextField.)
I am not sure how to go about this. I was thinking of sub-classing UITextField and trying to intercept the touch event as it is sent, but I can't figure out which methods to override to do this. Which methods should I override and how?
Or, if there is a better way to do this, let me know! I'm all ears, and not sure how to proceed.
This would involve several steps:
1.) Add a NSBoolean property that keeps track of whether the user has already tapped the field once recently (you get to decide what recently means here).
2.) Implement the textFieldShouldBeginEditing: method of the delegate assigned to your UITextField. If the user has tapped twice in quick succession (detectable by checking whether or not the boolean property is true), then return YES. If not, call your method, and then return NO.
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/