Multi-line TextField (similar to SMS) and / or 'Done' button in UITextView
Solution 1
Maybe you can build upon a class I wrote? It's the same as tttexteditor, without the ugly glitches: http://www.hanspinckaers.com/multi-line-uitextview-similar-to-sms
Solution 2
An old question, but after several hours I've figured out how to make it the same perfectly as in Instagram (it has the best algorithm among all BTW)
Initialize with this:
// Input
_inputBackgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, size.height - _InputBarHeight, size.width, _InputBarHeight)];
_inputBackgroundView.autoresizingMask = UIViewAutoresizingNone;
_inputBackgroundView.contentMode = UIViewContentModeScaleToFill;
_inputBackgroundView.userInteractionEnabled = YES;
[self addSubview:_inputBackgroundView];
[_inputBackgroundView release];
[_inputBackgroundView setImage:[[UIImage imageNamed:@"Footer_BG.png"] stretchableImageWithLeftCapWidth:80 topCapHeight:25]];
// Text field
_textField = [[UITextView alloc] initWithFrame:CGRectMake(70.0f, 0, 185, 0)];
_textField.backgroundColor = [UIColor clearColor];
_textField.delegate = self;
_textField.contentInset = UIEdgeInsetsMake(-4, -2, -4, 0);
_textField.showsVerticalScrollIndicator = NO;
_textField.showsHorizontalScrollIndicator = NO;
_textField.font = [UIFont systemFontOfSize:15.0f];
[_inputBackgroundView addSubview:_textField];
[_textField release];
[self adjustTextInputHeightForText:@""];
Fill UITextView delegate methods:
- (void) textViewDidBeginEditing:(UITextView*)textView {
[self adjustTextInputHeightForText:_textField.text];
}
- (void) textViewDidEndEditing:(UITextView*)textView {
[self adjustTextInputHeightForText:_textField.text];
}
- (BOOL) textView:(UITextView*)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString*)text {
if ([text isEqualToString:@"\n"])
{
[self performSelector:@selector(inputComplete:) withObject:nil afterDelay:.1];
return NO;
}
else if (text.length > 0)
{
[self adjustTextInputHeightForText:[NSString stringWithFormat:@"%@%@", _textField.text, text]];
}
return YES;
}
- (void) textViewDidChange:(UITextView*)textView {
[self adjustTextInputHeightForText:_textField.text];
}
And the trick is...
- (void) adjustTextInputHeightForText:(NSString*)text {
int h1 = [text sizeWithFont:_textField.font].height;
int h2 = [text sizeWithFont:_textField.font constrainedToSize:CGSizeMake(_textField.frame.size.width - 16, 170.0f) lineBreakMode:UILineBreakModeWordWrap].height;
[UIView animateWithDuration:.1f animations:^
{
if (h2 == h1)
{
_inputBackgroundView.frame = CGRectMake(0.0f, self.frame.size.height - _InputBarHeight, self.frame.size.width, _InputBarHeight);
}
else
{
CGSize size = CGSizeMake(_textField.frame.size.width, h2 + 24);
_inputBackgroundView.frame = CGRectMake(0.0f, self.frame.size.height - size.height, self.frame.size.width, size.height);
}
CGRect r = _textField.frame;
r.origin.y = 12;
r.size.height = _inputBackgroundView.frame.size.height - 18;
_textField.frame = r;
} completion:^(BOOL finished)
{
//
}];
}
Solution 3
Facebook has released an open-source package called Three20 that has a multi-line text field. You can use this pretty easily for an expanding text field.
As for the "Done" button, you can set your view controller as a UITextFieldDelegate
. Then use this method:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// Do whatever you want for your done button
return YES;
}
In the case of Three20, use this method of TTTextEditorDelegate
:
- (BOOL)textFieldShouldReturn:(TTTextEditor *)textField {
// Do whatever you want for your done button
return YES;
}
Solution 4
Well, I had a similar problem, and what I ended up using is actually create a disabled UITextField as the background and a UITextView above it to get the input... It sucks that iPhone API cannot have this by default. Also note that this does not auto-expand, but you can do this if you want by handling the textViewDidChange:
As for handling the return key, try implementing the following method from the UITextViewDelegate
:
- (void)textViewDidChange:(UITextView *)inTextView {
NSString *text = inTextView.text;
if ([text length] > 0 && [text characterAtIndex:[text length] -1] == '\n') {
inTextView.text = [text substringToIndex:[text length] -1]; // remove last return from text view
[inTextView resignFirstResponder]; // hide keyboard
}
}
Anonymouslemming
Updated on March 03, 2020Comments
-
Anonymouslemming about 4 years
I've been researching this for a few days now, and would appreciate a little help. Is there any way to generate a multi-line UITextField like Apple use in the SMS application? The useful thing about this control is that it has the 'sunk' appearance that makes it clear that it is a text entry box, but at the same time, it expands on each new-line character.
Failing that, if I'm forced to use a UITextView, can anyone advise how best to dismiss the keyboard ? Both the 'Done' and the 'Go' buttons just appear to generate newline characters ('\n'). This seems wrong to me - surely at least one of these should generate a different character, so that I can still allow for newline characters, but also dismiss my keyboard on a specific key press.
Am I missing something simple here ?
Thanks in advance :)