Ignore Tab character in UITextField... (iPad app) - iphone

I have a TableView with TextFields in each cell and I want to those textfields
ignore the character tab (\t).
When the tab key is pressed, the textField:shouldChangeCharactersInRange method it's not called
Does anyone knows how to do this? I know that there is no tab key in the iPad
keyboard but the blutooth and dock ones do and triggers a really weird behavior.
Thanks

This seems to be a problem with the tab (\t) character. This character is not handled like normal characters (e.g. a, b, c, 0, 1, 2, ...) and thus the
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string;
delegate method won't ever be called.
The result of using a tab on e.g. an external keyboard or in the simulator is that a currently active textfield resigns it's first responder status and the result of
[textField nextResponder]
will become first responder instead.
What IMO currently is a bug (iOS SDK 4.3) is that the delegate method
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
is only called once (when you return yes) and when you reselect the same textfield and use the tab key again, the method won't be called again.

Implement this method:
Add this in your AppDelegate.m
- (NSArray *)keyCommands {
static NSArray *commands;
static dispatch_once_t once;
dispatch_once(&once, ^{
UIKeyCommand *const forward = [UIKeyCommand keyCommandWithInput:#"\t" modifierFlags:0 action:#selector(ignore)];
UIKeyCommand *const backward = [UIKeyCommand keyCommandWithInput:#"\t" modifierFlags:UIKeyModifierShift action:#selector(ignore)];
commands = #[forward, backward];
});
return commands;
}
Add this method in the ViewController.m or subclass of UITextField in which you want to handle the TAB key event
- (void)ignore {
NSLog(#"Your Action");
}
Described in: How do you set the tab order in iOS?

Check to make sure the delegate for the UITextField is set either in IB or code.
Check to make sure your .h file has the UITextFieldDelegate specified
All should work now.

I think this is possible, but difficult. Basically, I would try to ensure that when the text field becomes the first responder, no other view can become the first responder. Then, pressing tab will do nothing. Then, you would have to reverse this effect when another view that actually could become first responder is selected, or when the text field resigns first responder.

Have you tried checking other characters in the range you're calling shouldChangeCharactersInRange with? That will make sure it's not being called properly (vis a vis a problem with the tab key specifically).
more on shouldChangeCharactersInRange here

Related

xcode 4.2.1 - custom keyboard - two UITextFields

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.

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.

Hiding keyboard when clear button is pressed in UITextField

Is there any way to hide the keyboard when a clear button of UITextField is pressed?
Yes, there is, although I suspect that doing so would violate the Apple Human Interface Guidelines.
To do so, add the following method to your view controller's implementation file. Then make the view controller into your textfield's delegate.
- (BOOL) textFieldShouldClear:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
The downside to this approach is if you ever want to prevent the textfield from clearing, your code becomes messy. Instead you might try to define a custom method and then connect it to the valueDidChange method and check for an empty value.
-(IBAction)hideKeyboardFromTextField:(id)sender{
//TODO: Check if the previous value was longer than one character to differentiate
//between backspace and clear.
//check if the editing caused the box to be empty
if([[sender value] isEqualToString:#""] || [sender value] == nil)
[sender resignFirstResponder];
}
}
The problem here is that you can't easily differentiate between a tap on the clear button and a tap on the delete button when there is one character in the UITextField.
As I said in the beginning of my answer, this is not advisable in the first place and as the answers here have shown, it is not so easy to implement. I don't think it's worth the hassle, considering the difficulty involved and the fact that it doesn't result in optimal user experience.
This code is definitely working for me to hide the key board while clearing out the content of the textfield
- (BOOL)textFieldShouldClear:(UITextField *)textField
{
textField.text = #"";
return NO;
}
Yep. Call resignFirstResponder on the text field in the delegate's textFieldShouldClear: method.
In UITextFieldDelegate
- (BOOL)textFieldShouldClear:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
But there is a problem with this. From the manual, "The text field calls this method in response to the user pressing the built-in clear button. (This button is not shown by default but can be enabled by changing the value in the clearButtonMode property of the text field.) This method is also called when editing begins and the clearsOnBeginEditing property of the text field is set to YES."
Note that, this method is called when editing begins if clearsOnBeginEditing is set to YES. So if you call resignFirstResponder in this method then editing will not begin actually. So you need to set clearsOnBeginEditing to NO. Obviously then the text field won't be cleared when editing begins.
Another IMPORTANT matter not directly related to the question. Hiding the keypad after tapping clear button is not a familiar behavior and Apple does NOT like changing the behavior of standard items. You may get a rejection for this.
Try this code:
[TextField performSelector:#selector(resignFirstResponder) withObject:nil afterDelay:0.1];
For Swift
In your UITextFieldDelegate
func textFieldShouldClear(_ textField: UITextField) -> Bool {
textField.resignFirstResponse()
return true
}

Unable to dismiss keyboard with UITextField

I cannot get textFieldShouldEndEditing to call. I have re created the links in interface builder and tried, but nothing seems to work. Any idea why this would not be called?
Edit
I am implementing both -textFieldShouldEndEditing and -textFieldDidFinishEditing. Adding the delegate for the textField didnt help either. The code I am using below is not triggering the log messages.
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
NSLog(#"Done editing...");
[textField resignFirstResponder];
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
NSLog(#"Done editing...");
}
Don't use -textFieldDidEndEditing. That gets called after the text field resigns first responder... which it hasn't yet because you haven't told it to because that method hasn't been called yet because first responder hasn't been resigned because you haven't told it to yet. Circular, chicken-and-egg sort of problem.
The delegate method you want is -textFieldShouldReturn. That gets called when the "return" key is pressed. Inside that, tell the text field to resign first responder, then return YES.
Also put a big clear custom button behind your form, and hook its touch-up-inside to a method that goes through all the text fields in the form and resigns first responder on each of them. So a background touch releases the keyboard too.
I saw it was a long-long time ago and I hope that since then you could solve the problem. Everybody tells you the right thing, but you have to take care of all at the same time! Let me just go through on all of them:
Make the promise first:
#interface yourViewController : UIViewController <UITextFieldDelegate>
Then make sure, you also hook up your textfields' delegates on the storyboard to the actual viewcontroller (yourViewController)!
When its done, implement the method in the right viewcontroller file (yourViewController.m):
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
Test it, and it should work now...
I hope it helps!
set the delegate to your TextField
In the interface Builder select your TextField, then press command + 2(Connections) and connect the delegate outled with the file's owner then save, and with that should work.
the delegate method are:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
}
Hope this can help you.
Have you set the delegate?
If not,set using
textField.delegate=self;
or else,
You must include UITextFieldDelegate in .h file
#interface yourViewController : UIViewController <UITextFieldDelegate>
EDIT:
You have to code in this delegate textFieldDidEndEditing not this textFieldShouldEndEditing

Focus on next valid key view on iPhone

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/