290

I am developing an application where user has to write some information. For this purpose I need a UITextField which is multi-line (in general UITextField is a single line).

As I'm Googling I find a answer of using UITextView instead of UITextfield for this purpose.

Juan Boero
  • 6,281
  • 1
  • 44
  • 62
raaz
  • 12,410
  • 22
  • 64
  • 81
  • 2
    use this third party classes import your xcode project and use it, its working too good link :https://github.com/adonoho/HPGrowingTextView – mahesh chowdary Nov 27 '13 at 07:11
  • Here is the small control I wrote exactly for that purpose. it has multiline support and also Done button for closing keyboard. feel free to use it https://code.google.com/p/galtextfield/ – Gal Blank Aug 14 '13 at 15:33

11 Answers11

490

UITextField is specifically one-line only.

Your Google search is correct, you need to use UITextView instead of UITextField for display and editing of multiline text.

In Interface Builder, add a UITextView where you want it and select the "editable" box. It will be multiline by default.

Undo
  • 25,519
  • 37
  • 106
  • 129
h4xxr
  • 11,385
  • 1
  • 39
  • 36
34

You can fake a UITextField using UITextView. The problem you'll have is that you lose the place holder functionality.

If you choose to use a UITextView and need the placeholder, do this:

In your viewDidLoad set the color and text to placeholders:

myTxtView.textColor = .lightGray
myTxtView.text = "Type your thoughts here..."

Then make the placeholder disappear when your UITextView is selected:

func textViewDidBeginEditing (textView: UITextView) {
    if myTxtView.textColor.textColor == ph_TextColor && myTxtView.isFirstResponder() {
        myTxtView.text = nil
        myTxtView.textColor = .white
    }
}

When the user finishes editing, ensure there's a value. If there isn't, add the placeholder again:

func textViewDidEndEditing (textView: UITextView) {
    if myTxtView.text.isEmpty || myTxtView.text == "" {
        myTxtView.textColor = .lightGray
        myTxtView.text = "Type your thoughts here..."
    }
}

Other features you might need to fake:

UITextField's often capitalize every letter, you can add that feature to UITableView:

myTxtView.autocapitalizationType = .words

UITextField's don't usually scroll:

myTxtView.scrollEnabled = false
Clay Ellis
  • 4,960
  • 2
  • 37
  • 45
Dave G
  • 12,042
  • 7
  • 57
  • 83
19

Ok I did it with some trick ;) First build a UITextField and increased it's size like this :

CGRect frameRect = textField.frame;
        frameRect.size.height = 53;
        textField.frame = frameRect;

Then build a UITextView exactly in the same area that u made my UITextField, and deleted its background color. Now it looks like that u have a multiple lines TextField !

Girish
  • 4,692
  • 4
  • 35
  • 55
Rudi
  • 4,304
  • 4
  • 34
  • 44
  • 2
    I used auto layout and pinned all the sides of the UITextField to the UITextView. Really great trick, thanks! – phatmann Dec 21 '13 at 17:02
  • please @phantmann , can you show us your code for auto layout? – Esteve Mar 07 '14 at 13:44
  • 9
    This creates a `UITextView`. The point of having a UITextField is that it behaves differently than a `UITextView`. – Nate Symer Aug 10 '15 at 19:16
  • 2
    There are a bunch of differences between `UITextView` and `UITextfield`: they inherit from `UIScrollView` vs `UIControl`, not-editable-by-default vs. editable-by-default, multiline vs. single-line, different delegate protocols, no-placeholder vs. placeholder. – Sam Ballantyne Nov 19 '16 at 18:14
  • `UITextView` is for paragraphs of text. Use it if you need a paragraph of text, and not otherwise. – Sam Ballantyne Nov 19 '16 at 18:16
  • 1
    This hack is useless. – OhhhThatVarun Apr 01 '20 at 14:21
9

Besides from the multiple line behaviour, the main difference between UITextView and UITextField is that the UITextView does not propose a placeholder. To bypass this limitation, you can use a UITextView with a "fake placeholder."

See this SO question for details: Placeholder in UITextView.

Community
  • 1
  • 1
MonsieurDart
  • 6,005
  • 2
  • 43
  • 45
2

Yes, a UITextView is what you're looking for. You'll have to deal with some things differently (like the return key) but you can add text to it, and it will allow you to scroll up and down if there's too much text inside.

This link has info about making a screen to enter data:

create a data entry screen

NANNAV
  • 4,875
  • 4
  • 32
  • 50
nevan king
  • 112,709
  • 45
  • 203
  • 241
2

If you must have a UITextField with 2 lines of text, one option is to add a UILabel as a subview of the UITextField for the second line of text. I have a UITextField in my app that users often do not realize is editable by tapping, and I wanted to add some small subtitle text that says "Tap to Edit" to the UITextField.

CGFloat tapLlblHeight = 10;
UILabel *tapEditLbl = [[UILabel alloc] initWithFrame:CGRectMake(20, textField.frame.size.height - tapLlblHeight - 2, 70, tapLlblHeight)];
tapEditLbl.backgroundColor = [UIColor clearColor];
tapEditLbl.textColor = [UIColor whiteColor];
tapEditLbl.text = @"Tap to Edit";

[textField addSubview:tapEditLbl];
DiscDev
  • 38,652
  • 20
  • 117
  • 133
2

use UITextView instead of UITextField

Monir Khlaf
  • 567
  • 7
  • 5
2
'override func viewDidLoad(){
super.viwDidLoad()
YOUR_TEXT_VIEW.textColor = UIColor.gray // YOUR PREFERRED PLACEHOLDER COLOR HERE
YOUR_TEXT_VIEW.text =  "YOUR DEFAULT PLACEHOLDER TEXT HERE"
YOUR_TEXT_VIEW.delegate = self
}'

This code block is enough. Please don't forget to set delegate in viewDidLoad or by storyboard just before to use the following extension:

extension YOUR_VIEW_CONTROLLER: UITextViewDelegate {
    
    func textViewDidBeginEditing (_ textView: UITextView) {
        if YOUR_TEXT_VIEW.text.isEmpty || YOUR_TEXT_VIEW.text == "YOUR DEFAULT PLACEHOLDER TEXT HERE" {
            YOUR_TEXT_VIEW.text = nil
            YOUR_TEXT_VIEW.textColor = .red // YOUR PREFERED COLOR HERE
        }
    }
    func textViewDidEndEditing (_ textView: UITextView) {
        if YOUR_TEXT_VIEW.text.isEmpty {
            YOUR_TEXT_VIEW.textColor = UIColor.gray // YOUR PREFERED PLACEHOLDER COLOR HERE
            YOUR_TEXT_VIEW.text =  "YOUR DEFAULT PLACEHOLDER TEXT HERE"
        }
    }   
}
James Bucanek
  • 3,299
  • 3
  • 14
  • 30
asilturk
  • 198
  • 1
  • 7
0

A supplement to h4xxr's answer in the above, an easier way to adjust the height of the UITextField is to select square border style in the attribute inspectors->Text Field. (By default, the border style of a UITextfield is ellipse.)

Reference: Answered Brian in here : How to set UITextField height?

Community
  • 1
  • 1
Tony
  • 1,405
  • 3
  • 20
  • 31
0

Use textView instead then conform with its delegate, call the textViewDidChange method inside of that method call tableView.beginUpdates() and tableView.endUpdates() and don't forget to set rowHeight and estimatedRowHeight to UITableView.automaticDimension.

user10078095
  • 83
  • 1
  • 5
-1

There is another option that worked for me:

Subclass UITextField and overwrite:

- (void)drawTextInRect:(CGRect)rect

In this method you can for example:

    NSDictionary *attributes = @{ NSFontAttributeName : self.font,
                                  NSForegroundColorAttributeName : self.textColor };

    [self.text drawInRect:verticalAlignedRect withAttributes:attributes];

This code will render the text using as many lines as required if the rect has enough space. You could specify any other attribute depending on your needs.

Do not use:

self.defaultTextAttributes

which will force one line text rendering

McFlys
  • 51
  • 1
  • 3