I have a scroll view which contains a UITextField and a UITextView. The UITextField return key is "Next" and when this is pressed I call [myTextView becomeFirstResponder]; A random new line is inserted into my textview so I start on the second line. How do I avoid this?
Also important to note that this does not happen when I tap directly on the UITextView rather than tapping the next key.
Thanks in advance!
One solution to solve this is when you implement the textFieldShouldReturn: delegate method, be sure to return NO, and not YES. By returning NO, the newline isn't passed on to the text field.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// move to next field or whatever you need
[myTextView becomeFirstResponder];
return NO;
}
Okay, this behaviour is due to a bug in iOS when becoming firstresponder within same run loop by using next button. To over come this you should do this manually.
First resign first responder from a textFied, and then make textView as a first responder. like this. Implement this delegate method.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
[textView performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
return YES;
}
Similar idea to performSelector, but using asynchronous dispatch queue (Swift 4 version):
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
DispatchQueue.main.async {
self.myTextView.becomeFirstResponder()
}
return true
}
Related
I'm working on an Objective-C Xcode project in Xcode 6. I have a textfield and a button that checks what's in the textfield when pressed.
However, I would like the code to run when enter key is pressed instead of the submit button.
I have seen that you can set the key equivalent for a button in Xcode however this option doesn't appear to feature in Xcode 6.
Implement textField delegate method.
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self callYourCodeWantToExecute];
//return YES; // want to hide keyboard
//return NO; // want keyboard
}
You need to:
Set delegate for textField
In your delegate object handle -(BOOL)textFieldShouldReturn:(UITextField *)textField i.e. do what you need to do when return pressed and return YES if you want to text field get return NO if you don't want to handle return for text field.
First make your file delegate for UITextField and then add this method to your code ..
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Follow the below steps.
Set delegate of UITExtfield
Add tag value if there are multiple textfield
Now call the delegate method of UITextfield same as below.
Swift
optional func textFieldShouldReturn(_ textField: UITextField) -> Bool
Hope this helps!
I have 2 UITextField in a ViewController. One brings up a UIDatePicker another brings up a KeyBoard(number pad). I then assign user inputs to two class variables, a NSDate variable and a NSNumber variable, in the following method.
-(void)textFieldDidEndEditing:(UITextField *)textField{
if (textField == self.datePickerTextField){
//update xxtime
self.xxTime = self.datePicker.date;
NSLog(#"...%#",self.xxTime);
}
if (textField == self.numberTextField) {
int val = [textField.text intValue];
self.xxNumber = [NSNumber numberWithInt:val];
NSLog(#"...%#",self.xxNumber);
}
}
If I tap the datePickerTextField first then the numberTextField, this method won't get called after I finish typing in the numberTextField.
So my question is how do I make this method to get called? Should I specify "resignFirstResponder" somewhere?
TIA
It will invoke didEndEditing once another control gains focus
According to the API,
This method is called after the text field resigns its first responder
status.
So if you want didEndEditing to be invoked, you need to call
[textField resignFirstResponder];
Yo are right you need to specify resignFirstResponder
- (BOOL)textFieldShouldReturn:(UITextField *)textField {//Text Field Delegate
if (textField == textField1) {
[textField1 becomeFirstResponder];
}else{
[textField resignFirstResponder];
}
return TRUE; }
this can used with textFieldDidEndEditing also
Please check what iOS you are using. Remember that if you are using iOS 10, there is a method that is replacing the old textFieldDidEndEditing called func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason)
I have a text field , and i need when the user presses it to show a custom picker.
The picker is shown fine , but the problem is that the keyboard appears on the bottom and i dont want that.
This is an iPad project which i am trying to convert from my iphone one. On the iPhone , this works well and the keyboard is always hidden.
What could i be missing/forgetting to do here ?
EDIT
For future reference what actually happened here , was that in fact both times (iphone & ipad) the keyboard was not hidden. I just thought that it was hidden in the iphone because my picker , which was popping from the bottom was hiding the keyboard as it was on top of it. But on ipad this wasnt the case.
Anyway i fixed it , using the delegate method suggested below.
Caution , i accepted this answer cause it was the one answering specifically what i wanted. The rest of the answers are correct and my considered better for other implementations.
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
// Here You can do additional code or task instead of writing with keyboard
return NO;
}
this delegate method will get called first when you hit to textfield and if you write NO as a boolean value means you dont want to begin editing so it will not present Keyboard.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textfield == yourtextField)
{
[textfield resignFirstResponder];
// Show you custom picker here....
return NO;
}
}
and you need to implement the uitextfielddelegate in the controller.
and give assign the delegate to yourtextField.
Use textfield delegate.
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return NO;
}
It looks like all of these answers take one approach, to simply deny the keyboard before it comes up. This prevents first responder status, which has many advantages.
One simple approach that allows you to maintain first responder status is to create an empty view and assign that to the inputView property on your input field. If you are using iOS 9 (or later?) you will also have to get rid of the inputAssistantItem objects as well.
UITextField *field = [[UITextField alloc] init];
field.inputView = self.emptyKeyboard.view;
UITextInputAssistantItem *aItem = [field inputAssistantItem];
aItem.leadingBarButtonGroups = #[];
aItem.trailingBarButtonGroups = #[];
Then if you want to control the field from an alternate view controller, you can do so by adding targets:
[field addTarget:self.numberPad action:#selector(editingBegan:) forControlEvents:UIControlEventEditingDidBegin];
[field addTarget:self.numberPad action:#selector(editingEnded:) forControlEvents:UIControlEventEditingDidEnd];
[field addTarget:self.numberPad action:#selector(fieldChanged:) forControlEvents:UIControlEventEditingChanged];
It is also possible to do this a lot more cleanly by subclassing UITextField.
Use the textField Delegate,
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
textField=nil;
return NO;
}
swift 3.0 version
First set the delegate for the text field
self.textfield.delegate = self
Then in an extension
extension ViewController: UITextFieldDelegate {
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
// Here you can do for Specific text Field by
if (textField==(the text field you don't want to show keyboard)) {
NSLog(#"don't show keyboard");
return NO;
}
else {
return YES;
}
}
Swift 3/4
Add:- UITextFieldDelegate in your class.
Add:- self.textField.delegate = self In ViewDidLoad
last one just add this func -
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}
I have a few UITextFields (within UITableViewCells) on my UIView with a "Save" UIButton. I want to do some basic validation on the UITextFields when the user clicks the "Save" button.
I have overridden textFieldDidEndEditing to save each of my UITextField data to an instance variable; however, if a user clicks the save button before either clicking the "Return" button of the UIKeyboard or clicking on another UITextField the data in my last UITextField is never saved to my instance variable and validation always fails.
I am looking for a way to trigger an "onBlur" (I know that's a JS thing)-type event to save my string in UITextField to my instance variable.
I've looked through the UITextFieldDelegate Protocol and I do not see anything like this.
Is there a method I may be missing?
to trigger textFieldDidEndEditing on your UITextField, you will need to call
[_txt resignFirstResponder];
were _txt is your UITextField
Please note that if you dont have a reference to _txt and you need to find the first responder in order to resign it
You could use the solution from this question Get the current first responder without using a private API
Then instead of calling
[_txt resignFirstResponder];
you would call
[self.view findAndResignFirstResponder];
Try this
// if we encounter a newline character return
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// enter closes the keyboard
if ([string isEqualToString:#"\n"])
{
[textField resignFirstResponder];
return NO;
}
return YES;
}
which will trigger
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
// Call webservice
return YES;
}
I have a UITextfield that i'd like to dismiss the keyboard for. I can't seem to make the keyboard go away no matter what code i use.
If you have multiple text fields and don't know which one is first responder (or you simply don't have access to the text fields from wherever you are writing this code) you can call endEditing: on the parent view containing the text fields.
In a view controller's method, it would look like this:
[self.view endEditing:YES];
The parameter forces the text field to resign first responder status. If you were using a delegate to perform validation and wanted to stop everything until the text field's contents were valid, you could also code it like this:
BOOL didEndEditing = [self.view endEditing:NO];
if (didEndEditing) {
// on to the next thing...
} else {
// text field must have said to first responder status: "never wanna give you up, never wanna let you down"
}
The endEditing: method is much better than telling individual text fields to resignFirstResponder, but for some reason I never even found out about it until recently.
[myTextField resignFirstResponder]
Here, second paragraph in the Showing and Hiding the Keyboard section.
I've discovered a case where endEditing and resignFirstResponder fail. This has worked for me in those cases.
ObjC
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder) to:nil from:nil forEvent:nil];
[self setEditing:NO];
Swift
UIApplication.shared.sendAction(#selector(resignFirstResponder), to: nil, from: nil, for: nil)
There are cases where no text field is the first responder but the keyboard is on screen.
In these cases, the above methods fail to dismiss the keyboard.
One example of how to get there:
push the ABPersonViewController on screen programmatically; open any contact;
touch the "note" field (which becomes first responder and fires up the keyboard);
swipe left on any other field to make the "delete" button appear;
by this point you have no first responder among the text fields (just check programmatically) but the keyboard is still there. Calling [view endEditing:YES] does nothing.
In this case you also need to ask the view controller to exit the editing mode:
[viewController setEditing:NO animated:YES];
I suggest you add and action on your header file:
-(IBAction)removeKeyboard;
And in the implementation, write something like this:
-(IBAction)removeKeyboard
{
[self.textfield resignFirstResponder];
}
In the NIB file, connect from the UITextFiled to the File's Owner on the option DidEndOnExit. That way, when you press return, the keyboard will disappear.
Hope it helps!
In your view controller YourViewController.h file, make sure you implement UITextFieldDelegate protocol :
#interface YourViewController : <UITextFieldDelegate>
#end
Then, in YourViewController.m file, implement the following instance method:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.yourTextField1 resignFirstResponder];
[self.yourTextField2 resignFirstResponder];
...
[self.yourTextFieldn resignFirstResponder];
}
To resign any text field in the app
UIApplication.shared.keyWindow?.endEditing(true)
This approach is clean and guarantied to work because the keyWindow is, by definition, the root view of all possible views displaying a keyboard (source):
The key window receives keyboard and other non-touch related events. Only one window at a time may be the key window.
This will resign one particular text field
// Swift
TextField.resignFirstResponder()
// Objective C
[TextField resignFirstResponder];
To resign any text field use below code
// Swift
self.view!.endEditing(true)
// Objective C
[self.view endEditing:YES];
as a last resort 💩
let dummyTextView = UITextView(frame: .zero)
view.addSubview(dummyTextView)
dummyTextView.becomeFirstResponder()
dummyTextView.resignFirstResponder()
dummyTextView.removeFromSuperview()
If you don't know which textField is the first responder you can find it. I use this function:
UIView *resignFirstResponder(UIView *theView)
{
if([theView isFirstResponder])
{
[theView resignFirstResponder];
return theView;
}
for(UIView *subview in theView.subviews)
{
UIView *result = resignFirstResponder(subview);
if(result) return result;
}
return nil;
}
Then in your code call:
UIView *resigned = resignFirstResponder([UIScreen mainScreen]);
You just replace yourTextFieldName with, you guessed it! your textfield. This will close the keyboard.
[yourTextFieldName resignFirstResponder];
-(void)methodName
{
[textFieldName resignFirstResponder];
}
call this method (methodName) with didEndOnExit
For Swift 3
You can hide the keyboard like this:
textField.resignFirstResponder()
If you want to hide the keyboard when the user press the "intro" button, you have to implement the following UITextFieldDelegate method:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
// your code
[textField reloadInputViews];
}
3 Simple & Swift steps
Add UITextFieldDelegate to your class as below:
class RegisterVC: UIViewController, UITextFieldDelegate {
//class implementation
}
in class implementation, add the delegate function textFieldShouldEndEditing::
internal func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.view.endEditing(true)
return true
}
and as a last step, set your UITextField(s) delegate(s) to self, in somewhere appropriate. For example, inside the viewDidLoad function:
override func viewDidLoad(){
super.viewDidLoad()
myTextField1.delegate = self
myTextField2.delegate = self
..
..
}
Now, whenever user hits the return key, keyboard will dismiss.
I prepared an example snippet too, you can check it from here.
Set up the "Did End On Exit" event in Xcode (right click on your text field).
Realize this method:
-(IBAction) closeKeyboard:(id) sender {
[_txtField resignFirstResponder];
}