1
votes

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?

6

6 Answers

3
votes

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)

3
votes

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.

1
votes
//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];

        }
  }
1
votes

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];
}
0
votes

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];
}

}

0
votes
  • (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    [txtView resignFirstResponder];
    

    return YES; }