How to make UITextView "Done" button resignFirstResponder? - iphone

I am trying to make my editable UITextView resign the keyboard (resignFirstResponder) when the user taps "Done." Using a UITextField, I have been able to do this with the following code:
- (IBAction)doneEditing:(id)sender {
[sender resignFirstResponder];
}
... and then to attach it to the relevant UITextField in Interface Builder to the action "Did End on Exit."
However, with a UITextView, I can't seem to access the "Did End on Exit" action. Any suggestions on how to make this happen?

The accepted answer didn't work for me. Instead, the following delegate method should be invoked like this:
- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]){
[textView resignFirstResponder];
return NO;
}else{
return YES;
}
}
Paste that into the class that you assign to be the UITextView delegate and it'll work.

new Answer
On your View, you'd have a UIBarButton ("Done") that is connected to the IBAction below:
- (IBAction)doneEditing:(id)sender {
[textView resignFirstResponder];
}
Where textView is your textView outlet defined in your .h file and connected in Storyboard or .xib file. Like this:
#property (retain, nonatomic) IBOutlet UITextView *textView;
old Answer
Check the following:
Is UITextViewDelegate specified
in .h
Implement delegate method
for uitextview:
textViewShouldEndEditing, return YES
make sure your .m (controller) is the
delegate for uitextview in IB
resignFirstResponder should now
work.

You can implement UITextViewDelegate and wait for "\n", in Swift 4 :
myTextView.delegate = self
// ...
extension MyViewController : UITextViewDelegate {
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
}

To have the done button dismiss the keyboard and resignFirstResponder you have to implement a delegate method.
In your .h implement the UITextFieldDelegate
#interface YourViewController : UIViewController <UITextFieldDelegate>
Then implement the textFieldShouldReturn in your .m
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Don't forget to link the delegate of UITextField to the file's Owner (very important)

Related

Textfield event is never called in delegate

In my interface I have:
#interface MainViewController : UIViewController <SKProductsRequestDelegate, SKPaymentTransactionObserver, UITextFieldDelegate> {
UITextField *Stock;
// ....
}
This is the implementation I have:
- (BOOL)Stock:(UITextField *)textField shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if([[textField text] isEqualToString:#"\n"]) {
[textField resignFirstResponder];
return NO;
}
return YES;
}
In the viewDidLoad I have Stock.delegate = self;
I am expecting this method is called after any character is typed in the text field. But this routine is never called. What is the problem?
Thanks
If this is a UITextField, you've just implemented a random method. The actual delegate method is
-textField:shouldChangeCharactersInRange:replacementString:
Try providing that one.
Did you wire the TextField (Stock in your case) Delegate to FileOwner ?
If not then try this in viewDidLoad method of the Controller
Stock.delegate = self;
Or you can just wire it in IB.
Declare MainViewController conforming UITextFieldDelegate:
#interface MainViewController : UIViewController < UITextFieldDelegate >
To be called this method of UITextFieldDelegate should be declared as:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
In code or in IB MainViewController should be set to be delegate.
Correct and it will be fired as supposed.

UITextView hide keyboard in iphone

I want to hide keyboard when a user presses return in UITextView object in iphone. However, mysteriously this is not working for UITextView but working for UITextField. I am unable to figure out why...
This is what I did:
1) I created a view based application in XCode4.
2) in .xib created UITextView, UITextField and UIButton objects
3) Marked both UITextField and UITextView delegates to File's Owner in Outlets
4) Added <UITextFieldDelegate> to #interface UIViewController in .h
5) Added textFieldShouldReturn function in .m
Here are the codes:
.h file
#interface keyboardDisappearViewController : UIViewController <UITextFieldDelegate>
{
UITextView *textBoxLarge;
UITextField *textBoxLittle;
}
#property (nonatomic, retain) IBOutlet UITextView *textBoxLarge;
#property (nonatomic, retain) IBOutlet UITextField *textBoxLittle;
- (IBAction)doSomething:(id)sender;
#end
.m file
- (BOOL) textFieldShouldReturn:(UITextField *)theTextField
{
NSLog(#"textFieldShouldReturn Fired :)");
[textBoxLarge resignFirstResponder];
[textBoxLittle resignFirstResponder];
return YES;
}
Amazingly, the keyboard is disappearing in case of textBoxLittle (UITextField) but not in case of textBoxLarge(UITextView)
As a further check I, made the button to call function doSomething
- (IBAction)doSomething:(id)sender {
[textBoxLarge resignFirstResponder];
[textBoxLittle resignFirstResponder];
}
When I am pressing the button, keyboard is disappearing in both textboxes.
Its driving me nuts why textFieldShouldReturn is working for small textbox, but NOT for large textbox.
Please Help!
Three things:
Make your view implement UITextViewDelegate.
#interface keyboardDisappearViewController : UIViewController
<UITextFieldDelegate, UITextViewDelegate>
Add the following method:
- (BOOL)textView:(UITextView *)textView
shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
if ([text isEqualToString:#"\n"])
{
[textView resignFirstResponder];
}
return YES;
}
Set the file's owner as delegate for the UITextView in the interface builder.
(BTW: Solution copied from the comments to the previous answer, as it took me a while to extract. I though others could benefit from my experience.)
You need to write code in UITextViewDelegate and assign it to your class.
Simple trick
Set delegate for your text view and then
doSomething
{
}
action connect to ext view for control event didEndOnExit and tuchupinside
// To dismiss key board when user clicks enter/return
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if([text isEqualToString:#"\n"])
{
[textView resignFirstResponder];
return NO;
}
return YES;
}
Use this code
Inherit UITextViewDelegate protocol in your Viewcontroller add the text
#interface YourViewController () <UITextViewDelegate>
In viewDidLoad set yourself as a delegate:
yourUITextView.delegate = self;
Implement the delegate method below:
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
return NO;
}
Key Points
Someone needs to be listening for the Return Key press
UITextFieldDelegate
textFieldShouldReturn(textField : UITextField)
Someone needs to manually dismiss the keyboard
resignFirstResponder()
#1: Create a UITextFieldDelegate and assign it as the delegate to your UITextField -
exampleTextField.delegate = yourUITextFieldDelegate;
#2: Have 'yourUITextFieldDelegate' contain the following -
func textFieldShouldReturn(textField : UITextField) -> Bool {
self.titleField.resignFirstResponder(); //Here's the key!!!!!
return true; //true just says 'default behavior'
}
If you came here looking for the Swift solution, like I did, here you are :)
extension keyboardDisappearViewController : UITextViewDelegate {
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if(text == "\n") {
textView.resignFirstResponder()
}
return true
}}
You have coded in the .h file:
#interface keyboardDisappearViewController : UIViewController <UITextFieldDelegate>
{
UITextView *textBoxLarge;
UITextField *textBoxLittle;
}
#property (nonatomic, retain) IBOutlet UITextView *textBoxLarge;
#property (nonatomic, retain) IBOutlet UITextField *textBoxLittle;
- (IBAction)doSomething:(id)sender;
#end
It should be:
#interface keyboardDisappearViewController : UIViewController <UITextFieldDelegate>
{
UITextView *textBoxLarge;
UITextField *textBoxLittle;
}
#property (nonatomic, retain) IBOutlet UITextField *textBoxLarge;
#property (nonatomic, retain) IBOutlet UITextField *textBoxLittle;
- (IBAction)doSomething:(id)sender;
#end

UITextField keyboard Issue

I have such a problem: I have a UITextField in my UITableViewCell. When I tap on that text field -> keyboard appears, but when I press Enter button keyboard don't disappear. I need such a behavior for my text field and keyboard:
When I pressed Enter, Esc - keyboard must disappear.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
Where textField is UITextField in UITableViewCell
Implement textFieldShouldReturn: method in textField's delegate and call [textField resignFirstResponder] there - that will hide keyboard when return key is pressed.
I'm not sure if that will work for 'Esc' as well, but there's no such key on real device anyway so it must not be a problem
Try this
[txtField setReturnKeyType:UIReturnKeyDone];
txtField.enablesReturnKeyAutomatically=YES;
This may be an old post but I found it searching for the answer so chances are someone else might so don't shoot me for posting.
Just wanted to add
don't forget to make the delegate connection in IB for the UITextField
#interface Untitled2ViewController : UIViewController <UITextFieldDelegate>
{
IBOutlet UITextField *text;
}
#property (nonatomic, retain) IBOutlet UITextField *text;
#end
//m file
#import "Untitled2ViewController.h"
#implementation Untitled2ViewController
#synthesize text;
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
In xib file I set: Return Key: Done, Auto-anabling return key. I also tried without it, and still no reaction. Keyboard don't hides.
Write this code to create UITextLabel
UITextField *username = [[UITextField alloc]initWithFrame:CGRectMake(10.0f, 10.0f, 110.0f, 30.0f)]
[username setReturnKeyType:UIReturnKeyNext];
[username setDelegate:self];
[self.view addSubview:username];
Now to resign write this code.
-(void)resignKeyboard
{
if([username isEditing])
{
[username resignFirstResponder];
}
}
I hope it works for you.
try this
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
or this is for anywhere in the view
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}

-(void)textFieldDidBeginEditing:(UITextField *)sender.. this function is not called when i select textfield?

I m using -(void)textFieldDidBeginEditing:(UITextField *)sender this function in my application. this is not called when i select the textfield.
here's the code...
-(void)textFieldDidBeginEditing:(UITextField *)sender{
if([sender isEqual:txtName])//txtName is the IBOutlet of the UITextField
{
NSLog(#"Name");
}
else{
NSLog(#"NO_Name");
}
}
Did you set delegate of UITextField's instance to current view controller like this:
textField.delegate = self; (self means the instance where callback textFieldDidBeginEditing is overridden)
Make sure to complete 2 simple steps
1 - Implement the delegate UITextFieldDelegate
#interface yourViewController : UIViewController <UITextFieldDelegate>
2 - Set the delegate
yourTextField.delegate = self
If you have many text fields in your view, you can set delegate for all of your text fields like this
for (id subView in self.view.subviews)
{
if ([subView isKindOfClass:[UITextField class]]) {
[subView setDelegate:self];
}
}
You must include UITextFieldDelegate in .h file
#interface yourViewController : UIViewController <UITextFieldDelegate>
You must include UITextFieldDelegate in your .h file, and also add YourTextField.delegate = self

Insert date/time in UITextView when user hits return

Im trying to Insert the current date/time whenever the users hits the return key or starts typing on a UITextView in Xcode but not quite sure where to start.
I know this method is for when clicking into the TextView but doesn't seem to work:
- (void)textViewDidBeginEditing:(UITextView *)textView {
self.txtDetail.text = [self.txtDetail.text stringByAppendingString:#"Hello!"];
}
Thanks
Update:
DetailViewController.h
#interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate> {
UITextView *txtDetail;
}
#property (nonatomic, retain) IBOutlet UITextView *txtDetail;
- (void)textViewDidBeginEditing:(UITextView *)textView;
DetailViewController.m
#synthesize txtDetail;
- (void)textViewDidBeginEditing:(UITextView *)textView {
NSLog(#"Hello");
self.txtDetail.text = [self.txtDetail.text stringByAppendingString:#"Hello!"];
}
Update02:
Ive added this to my .m files:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
BOOL shouldChangeText = YES;
if ([text isEqualToString:#"\n"]) {
// Find the next entry field
txtDetail.text = [txtDetail.text stringByAppendingString:#"\nhey\n"]; }
textView.editable = YES;
shouldChangeText = NO;
[textView becomeFirstResponder];
return shouldChangeText;
}
I get the desired effect (Hey is added in whenever i press return on the keyboard) but i now can't type anything... any ideas?
You have to declare you controller as implementing the UITextViewDelegate Protocol and then connect it as the text view's delegate. Otherwise it never receives the delegate messages at all.
Then you have to implement:
– textView:shouldChangeTextInRange:replacementText:
... to return YES/TRUE otherwise no text gets added.
Update02:
You need to implement all the UITextViewDelegate protocol methods that have a return. If you don't, the text view assumes a NO by default.
See: Text and Web Programming Guide: Managing TextFields and TextViews
You also need to understand the Delegate Pattern.
Replace your method with the below method
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
BOOL shouldChangeText = YES;
if ([text isEqualToString:#"\n"] && textView == detailText)
{
// Find the next entry field
txtDetail.text = [txtDetail.text stringByAppendingString:#"\nhey\n"];
textView.editable = YES;
shouldChangeText = NO;
[textView becomeFirstResponder];
}
return shouldChangeText;
}
The mechanics of delegate calls is a very important part of iOS programming. There is a doc on it in the Apple libraries, and it is also discussed in many good books. The Apress book "Beginning iPhone Programming" is very good and covers delegate methods.