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.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Diffrence between textfieldshouldendediting and textfieldDidendediting in iPhone
What is the diffrence between textFieldShouldendEditing and textfieldDidEndEditing methods? and when will use these methods.
From documentation:
textFieldShouldendEditing:
This method is called when the text field is asked to resign the first responder status. This might occur when your application asks the text field to resign focus or when the user tries to change the editing focus to another control. Before the focus actually changes, however, the text field calls this method to give your delegate a chance to decide whether it should.
textfieldDidEndEditing:
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.
So, the textFieldShouldendEditing:method will be called before textfieldDidEndEditing:method
textFieldShouldendEditing will call when your textField is about to end edit mode. It has a BOOL return type. If you set return NO than your textField will not be resignFirstResponder and remain in editing mode and textfieldDidEndEditing is not going to call.
while textfieldDidEndEditing this is method which tell you that your text field not in editing mode and your keyboard is down.
For more details plz refer UITextFieldDelegate Protocol
Hope this helps :)
textFieldDidEndEditing:
is called when the text field resigns as the first responder. So you can then get the value entered from the user.
textFieldShouldendEditing: is used to check if the key entered by the user should be displayed on the text field or not. So if you return NO the key is not displayed.
Imagine a label where you want to restrict the number of letters entered. You can use the above to check how many characters are entered and if they have reached the limit, return the value NO which basically doesn't take any new key strokes.
You can check the reference doc for more info.
I have created a custom keyboard and I have two text fields.
I am calling [firstTextField becomeFirstResponder] in my viewDidLoad
to have my keyboard visible.
How can I know which text field is currently active so that I write what the user is typing from the keyboard to the respected textField?
I have tried - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField but it is not being called
any idea?
You should be able to use isFirstResponder to determine which of your two UITextFields is currently active.
if ([firstTextField isFirstResponder]) {
...
}
else {
...
}
To get textFieldShouldBeginEditing to be called, you need to set the delegate outlets for both your text fields to whatever view controller (or wherever) the textFieldShouldBeginEditing method lives in.
You can set the delegates programmatically (e.g. firstTextField.delegate = self;) or via the XIB file.
And your intuition is correct, once textFieldShouldBeginEditing gets called, you will know (from the textField parameter) which field the user is currently typing in.
For some reason, resignFirstResponder is not working. I am not sure why? I have tried to call it from textFieldDidEndEditing and nothing happens. A NIB is being used and each's delegate is pointing to files owner.
What needs to be done to get the keyboard to dismiss?
Thanks.
Don't use -textFieldDidEndEditing. That's called after the text field resigns firstResponder status, which is what you're trying to use it as a hook to make happen. Cart before horse, chicken-and-egg kind of problem.
Instead use -textFieldShouldReturn to get triggered when the return key is pressed (and remember to return YES; from that.) Also float a clear custom button behind the elements of the view and handle a "background tap" that goes through all the text fields on your view and resigns first responder on the lot of them.
actually you should return NO so that the text field does not begin editing at all. If it does, the firstresponder gets set and the keyboard pops up again.
Make sure your setting your delegates for the textfield.
myTextField.delegTe = self;
And you are using in your header:
<UITextFieldDelegate>
EDIT:
Try:
if(textField == myTextField){
[textField resignFirstResponder];
}
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/
Is there a way to prevent the user from moving the cursor in a UITextField? I'd like it to stay at the end of the string.
This is an old question, but I was looking for an answer to the same question, and found a solution.
It is actually quite simple to prevent the user from moving the cursor. Just subclass UITextField and provide the following implementation of caretRectForPosition:
- (CGRect)caretRectForPosition:(UITextPosition *)position
{
return [super caretRectForPosition:self.endOfDocument];
}
NO SUBCLASS needed.
You Could use UITextFieldDelegate. It will make disable magnifying glass & text selection.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
textField.userInteractionEnabled = NO;
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
textField.userInteractionEnabled = YES;
}
NB: This is just a bypass.
There's no way to prevent them from moving the cursor. You can, however, prevent them from editing the text except at the end by implementing the
– textField:shouldChangeCharactersInRange:replacementString:
method in your text field's delegate.
Edit: you can also set userInteractionEnabled to NO so that the user can't tap the field. Call becomeFirstResponder manually so that the field gets focus since the user can't tap to focus.
I'd suggest to check the gestureRecognizers property.
You will find a lot of them in the array and might want to either remove them all or to find the ones that triggers the event you want to intercept and remove/replace it.
I used it to remove copy/paste and magnifying glass functionalities from an UITextField
I haven't check if you can disable the magnifying glass, but the recommended way to selectively disable editing behavior in a UIResponder (and thus a UITextField) is to implement canPerformAction:withSender of UIResponder.
See UIResponder documentation.
Maybe if you return "NO" for the select and selectAll action you can disable it.
Another, more brutal, way is to intercept any touch event and reset the cursor to the end.