I have a UITextView. I implemented a navigationBar UIBarButtonItem to respond to a touch and resign the firstResponder for my UITextView.
But, when the selector method is called, the keyboard doesn't get dismissed. I checked the UITextView's responder status with isFirstResponder and it returns YES. I also checked it with canResignFirstResponder and the return value is NO.
I must be missing something here...why is it returning NO?
I get that I can override canResignFirstResponder by subclassing UITextView, but I'd like to avoid that if possible.
Here's a code snippet:
- (void) commentCancelButtonTouched:(id)sender
{
NSLog(#"Cancel button touched");
[self.navigationBar popNavigationItemAnimated: NO];
if ([self.textInput.textView canResignFirstResponder] == NO) {
NSLog(#"I don't want to resign!");
}
[self.textInput.textView resignFirstResponder];
}
Just in case anyone wants to hide the keyboard when you touch outside of the textview, it's pretty easy...
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.xFront resignFirstResponder];
}
xFront is my outlet to my UITextView.
Addressing your UITextField by way of a UIView subclass is a little non-standard. If I were you I'd get myself a direct handle on that UITextField right from inside your view controller. Set it up as a synthesized property of your view controller, give it the keyword IBOutlet so you can talk about it in Interface Builder, then make sure the outlet is hooked up to the text field.
In other words, rather than talking about self.textInput.textView, you want to be talking about self.textView directly. And double-check your IB outlet hookup, because I suspect that's where the real trouble is.
I figured it out. I had a 'UITextViewDelegate' method in my 'textInput' view, textViewShouldEndEditing that was overrided to return NO. Changed it to YES and it solved the problem.
Related
i have a screen having navigation controller and text field. when i move next and come back i want the keyboard should be hidden in first screen. I am hiding keyboard like on textfield event.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
But how to do that in View related events so that whenever my view appears keyboard is hidden..
Pls guide/Help.
thanks in adv.
I think this is also a good way to remove keyboard with in iOS App if your UITextView or UITextField not connected through the IBOutlet.
If you want to Hide Keyboard with UIViewController LifeCycle Events like with viewWillAppear or etc. Follow this
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self view] endEditing:YES];
}
Otherwise if you object connected using IBOutLet this code will work fine as you describe too.
[yourTextField resignFirstResponder];
Add this code to your ViewWillAppear :
for(id obj in self.view.subviews)
{
if([obj isKindOfClass:[UITextField class]])
{
[obj resignFirstResponder];
}
}
This would take in all the textfields in that particular view here it is the whole view and add the code you had written previously for removing the keyboard.
A good habit is to write this code in your screen's -viewWillDisappear. So, when you navigate from one screen to another at that time it will remove the keyboard from that screen.
- (void)viewWillDisappear:(BOOL)animated
{
[self.view endEditing:YES];
[super viewWillDisappear:animated];
}
For multiple textFields, it is better to use -endEditing for that particular view instead of -resignFirstResponder for any single textField. Take a look at my Answer.
//This is for Swift
override func viewWillAppear(animated: Bool)
{
self.view.endEditing(true)
}
The thing that you are doing wrong is , when you are moving back previous controller to the current controller , the keyboard is up due to the selected textfield of previous controller .
And in the current controller the code:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self view] endEditing:YES];
}
It will not work as no textfield is selected at this controller. So what you need to do is write the same code in the previous controller viewWillDisappear Method it will surely resolve your Problem .
- (void)viewWillDisappear:(BOOL)animated
{
[self.view endEditing:YES];
[super viewWillDisappear:animated];
}
I want to dismiss my keyboard as I press RETURN key.
I have tried by putting button in view's back side.
But how can I do this by pressing RETURN key?
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
Don't forget to add the delegate UITextFieldDelegate
I'm presuming you're talking about a UITextField rather than a UITextView as your question isn't that clear? If so then ensure your class is marked as a UITextFieldDelegate in the interface file,
#interface MyController: UIViewController <UITextFieldDelegate> {
UITextField *activeTextField;
// ...remainder of code not show ...
}
and then you should implement the two delegate methods as below,
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
activeTextField = textField;!
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
activeTextField = nil;
[textField resignFirstResponder];
return YES;
}
However if you're using a UITextView then things are a bit more complicated. The UITextViewDelegate protocol lacks the equivalent to the textFieldShouldReturn: method, presumably since we shouldn’t expect the Return key to be a signal that the user wishes to stop editing the text in a multi-line text entry dialog (after all, the user may want to insert line breaks by pressing Return).
However, there are several ways around the inability of the UITextView to resign as first responder using the keyboard. The usual method is to place a Done button in the navigation bar when the UITextView presents the pop-up keyboard. When tapped, this button asks the text view to resign as first responder, which will then dismiss the keyboard.
However, depending on how you’ve planned out your interface, you might want the UITextView to resign when the user taps outside the UITextView itself. To do this, you’d subclass UIView to accept touches, and then instruct the text view to resign when the user taps outside the view itself.
Create a new class,
#import <UIKit/UIKit.h>
#interface CustomView : UIView {
IBOutlet UITextView *textView;
}
#end
Then, in the implementation, implement the touchesEnded:withEvent: method and ask the UITextView to resign as first responder.
#import "CustomView.h"
#implementation CustomView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
}
return self;
}
- (void) awakeFromNib {
self.multipleTouchEnabled = YES;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"touches began count %d, %#", [touches count], touches);
[textView resignFirstResponder];
[self.nextResponder touchesEnded:touches withEvent:event];
}
#end
Once you’ve added the class, you need to save all your changes, then go into Interface Builder and click on your view. Open the Identity inspector in the Utility pabel and change the type of the view in your nib file to be your CustomView rather than the default UIView class. Then in the Connections Inspector, drag the textView outlet to the UITextView. After doing so, and once you rebuild your application, touches outside the active UI elements will now dismiss the keyboard. Note however that if the UIView you are subclassing is “behind” other UI elements, these elements will intercept the touches before they reach the UIView layer. So while this solution is elegant, it can be used in only some situations. In many cases, you’ll have to resort to the brute force method of adding a Done button to the navigation bar to dismiss the keyboard.
I hope you have done UIViewController <UITextFieldDelegate> and yourTextField.delegate=self;
and then in the delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
{
[textField resignFirstResponder];
return YES;
}
Make sure your view controller class is a delegate for your UITextField and then use the delegate method in that class:
#pragma mark - Delegate Methods
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
// Dismiss the keyboard when the Return key is pressed.
[textField resignFirstResponder];
return YES;
}
I have an application which has a couple of UITextField present to allow my user to enter their age, and another numerical value. Ideally, I want the keyboard to bring up the numeric keypad when the TextField is being edited. At present I have it set to Numer and Punctuation merely to make use of the 'Done' button to dismiss the keyboard as the Numeric pad does not have a done button.
In an attempt to use the Numeric keypad, I have tried to set it to dismiss by tapping the background of my main view.
-(IBAction)backgroundTapped:(id)sender;
I created the above action in my header file.
-(IBAction)backgroundTapped:(id)sender {
[ageEntry resignFirstResponder];
}
I have expanded on the above method in my implementation file to tell the ageEntry TextField to resignFirstResponder. I have also changed my main view to a UIControl class and connected the buttonTapped action to the relevant alert through Interface Builder. Yet when I touch the background nothing happens.
Any ideas?
Just detect the touch in your viewController's view using the method
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[urAgeField resignFirstResponder];
[urOtherField resignFirstResponder];
}
and resign the keyboard in this method
A much easier method is to add a inputAccessoryView to your text field. This input accessory view can be a UIToolbar with a single UITabBarButton for your Done button.
Much less of a hack, and will look like the accessory view that is used in for example Safari to dismiss the keyboard.
i had a similar problem. here is the solution..
EDITED
add
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(tap:)];
tap.numberOfTapsRequired = 1;
[self addGestureRecognizer:tap];
}
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
[ageEntry resignFirstResponder];
}
I am developing an iPhone application which requires a multiline text field (UITextView) to capture some text.
When the user touches inside the textView it becomes firstResponder and displays the keyboard. What I really need it to do is remove the keyboard when the user is finished. Normally with a text field the return/done button press would signal the end of typing and I would use the delegate to resign first responder. However with a multiline textview I want the user to be able to add a new line so that is not possible.
My next option would be to resign first responder if there is a touch up outside of the text view. The problem here is that there are no events declared on UITextView which I can see in interface builder.
How can I create a multiline text field in an iPhone app which will release first responder at a sensible time when the user is done with it?
You can use a DONE button on the navigation bar:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneAction:)];
}
to dismiss the keyboard, handle the event with something like:
- (void) doneAction: (id) sender{ [textView resignFirstResponder]; }
(remember .h file declarations)
I'm guessing you are lamenting the "missing" Done button on the keyboard which is return on a multi line UItextView, correct me if i'm wrong.
The obvious approach seems to have another button on your interface that resigns first responder.
I don't think some clever code that hides the keyboard upon some event would be very intuitive to use.
The Apple Notes application uses its top right done button to resign first responder, an approach like this seems sensible.
//If user touches outside of the keypad, then the keypad will go away
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if (touch.tapCount >= 1) {
[ZLabel resignFirstResponder];
}
}
You can create an invisible button that covers all screen and than add a method to it. I think sth like this will work.
- (IBAction)backgroundClick:(id)sender{
[textView resignFirstResponder];
}
If you are completely set on having the 'done' key on the keyboard, the method I use is check the last character in the UITextView when the contents changes. If the last character is a new line, then the user has hit the done button. I would second Neil's view that there should be another button, but sometimes the customer gets what the customer wants.
Obviously you will have to set the delegate for the UITextView to point to the class in which this method lives. The - (void)textViewDidChange:(UITextView *)inTextView method is part of the UITextViewDelegate protocol.
- (void)textViewDidChange:(UITextView *)inTextView {
NSString *text = inTextView.text;
if ([text length] > 0 && [text characterAtIndex:[text length] -1] == '\n') {
message = [text substringToIndex:[text length] -1];
[delegate messageEdited];
[self removeFromSuperview];
}
}
(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
[txtView resignFirstResponder];
return YES;
}
How to Hide Keyboard by pressing Returnkey
There is a couple of things you need to remember. The number #1 part developers forget to set is the delegate of the textField.
If you are using the Interface Builder, you must remember that you need to set the delegate of the textField to the file Owner.
alt text http://www.thoughtblog.com/imgs/delegate.png
If you are not using Interface Builder then make sure you set the delegate of the textfield to self. I also include the returnType. For Example if the textField was called gameField:
gameField.delegate = self;
gameField.returnType = UIReturnKeyDone;
You must also implement the UITextFieldDelegate for your ViewController.
#interface YourViewController : UIViewController <UITextFieldDelegate>
Finally you need to use the textFieldShouldReturn method and call [textField resignFirstResponder]
-(BOOL) textFieldShouldReturn:(UITextField*) textField {
[textField resignFirstResponder];
return YES;
}
All your textFields will use this same method so you only need to have this setup once. As long as the delegate is set for the textField, the UITextFieldDelegate is implemented for the interface, you add the textFieldShouldReturn method and call the
resignFirstResponder your set.
The keyboard only shows up when something editable (usually a UITextField) has become the first responder. Therefore, to make the keyboard go away, you have to make the textField not be the firstResponder anymore. Fortunately, it's one line of code:
[myTextField resignFirstResponder];
You really need to include more information with your question, but I think this might be what you are looking for:
First, make your view controller implement the UITextFieldDelegate:
#interface MainViewController : UIViewController <UITextFieldDelegate> {
Then add this method to the controller:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
Read the UITextFieldDelegate documentation to see what else you can do.
Use these two methods:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
activeTextField = textField;
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
activeTextField = nil;
[txtPassword resignFirstResponder];
[txtUserName resignFirstResponder];
return YES;
}
Please make sure you have given delegates to each textfields. For that you should go to the view. Right click . set the delegate to view.