Objective C: How to create a multi-line UITextField?

Possible Duplicate:
How to create a multiline UITextfield?

How can I implement a multiple line textfield like what I see in the iPhone messaging app?

  • FloatValue with 2 decimals from textField
  • Dispatch queues: How to tell if they're running and how to stop them
  • iphone app doesn't respond after starting in landscape orientation on iPad
  • Getting detected data from the UITextView
  • Connecting slider to view - Swift
  • `save(to:for:completionHandler:)` of `UIDocument` crashes
  • enter image description here

    It seems like the once the length of input exceeds the length, a second line will be auto created.

    EDIT: Updated to clarify my challenges in using a UITextView

    For me, I would like to model the feel and look of the UITextView to that as shown below. I am not sure how I can do it with UITextView as suggested. For example

    1) How to expand the box dynamically if my text needs to overflow to next line

    2) How to add the border and styling as shown below

    3) How to attach the text box right above the keyboard (instead of in the view)

    I know that Instagram have this as well, if someone can point me to the correct direction, that will be great. Thanks in advnce

    enter image description here

    2 Solutions Collect From Internet About “Objective C: How to create a multi-line UITextField?”

    Check these answers:

    How to create a multiline UITextfield?

    How to create a multiline UITextfield?

    http://brettschumann.com/blog/2010/01/15/iphone-multiline-textbox-for-sms-style-chat

    And definitly try Three20 which is a great library used in many app like Facebook.


    Edit: Added extract from BrettSchumann blog

    #import <uikit uikit.h="">
    @interface MultilineTextboxViewController : UIViewController {
        IBOutlet UIView *viewTable;
        IBOutlet UIView *viewForm;
        IBOutlet UITextView *chatBox;
        IBOutlet UIButton   *chatButton;
    }
    
    @property (nonatomic, retain) UIView *viewTable;
    @property (nonatomic, retain) UIView *viewForm;
    @property (nonatomic, retain) UITextView *chatBox;
    @property (nonatomic, retain) UIButton *chatButton;
    
    - (IBAction)chatButtonClick:(id)sender;
    @end
    </uikit>
    

    With that done and while we are setting everything up lets go and add our items to our main (.m) file at the same time not forgetting to de-allocate them as well.

    @synthesize viewTable;
    @synthesize viewForm;
    @synthesize chatBox;
    @synthesize chatButton;
    
    - (void)dealloc{
        [viewTable release];
        [viewForm release];
        [chatBox release];
        [chatButton release];
        [super dealloc];
    }
    

    In the (void)viewDidLoad method we need to add some notification observers so that we can see when the keyboard is shown or hidden and when the user presses a key on the keyboard.

    - (void)viewDidLoad {
        //set notification for when keyboard shows/hides
        [[NSNotificationCenter defaultCenter] addObserver:self 
                            selector:@selector(keyboardWillShow:) 
                            name:UIKeyboardWillShowNotification 
                            object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self 
                            selector:@selector(keyboardWillHide:) 
                            name:UIKeyboardWillHideNotification 
                            object:nil];
    
        //set notification for when a key is pressed.
        [[NSNotificationCenter defaultCenter] addObserver:self 
                            selector: @selector(keyPressed:) 
                            name: UITextViewTextDidChangeNotification 
                            object: nil];
    
        //turn off scrolling and set the font details.
        chatBox.scrollEnabled = NO;
        chatBox.font = [UIFont fontWithName:@"Helvetica" size:14]; 
    
        [super viewDidLoad];
    }
    

    When focus is set on the textview the keyboard will be shown. Because the textview and buttons are both in the lower viewForm on the screen, the keyboard is going to ride up and go over these. So what we want to do is adjust the height of viewTable and the position of viewForm. We do this in the following method.

    -(void) keyboardWillShow:(NSNotification *)note{
        // get keyboard size and loction
        CGRect keyboardBounds;
        [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
    
        // get the height since this is the main value that we need.
        NSInteger kbSizeH = keyboardBounds.size.height;
    
        // get a rect for the table/main frame
        CGRect tableFrame = viewTable.frame;
        tableFrame.size.height -= kbSizeH;
    
        // get a rect for the form frame
        CGRect formFrame = viewForm.frame;
        formFrame.origin.y -= kbSizeH;
    
        // animations settings
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:0.3f];
    
        // set views with new info
        viewTable.frame = tableFrame;
        viewForm.frame = formFrame;
    
        // commit animations
        [UIView commitAnimations];
    }
    

    Now that the keyboard is shown and our views have been adjusted we want to capture the text the user is entering and see if we need to make any adjustments to the chatBox. Lucky for us we can use the CGSize object, pass it some text, and tell the object what size we would want to constrain the text to and from that we can calculate get height.Now this is where a little trial and error comes in. The line varies with the size of the font and your width of your CGSize object will vary with the width of your UITextview so you will have to experiment a little. The value of 12 use in the code below is the difference in height between the starting height of my chatBox and the line height based on the font that I have set.

    -(void) keyPressed: (NSNotification*) notification{
        // get the size of the text block so we can work our magic
        CGSize newSize = [chatBox.text 
                    sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] 
                    constrainedToSize:CGSizeMake(222,9999) 
                    lineBreakMode:UILineBreakModeWordWrap];
        NSInteger newSizeH = newSize.height;
        NSInteger newSizeW = newSize.width;
    
        // I output the new dimensions to the console 
        // so we can see what is happening
        NSLog(@"NEW SIZE : %d X %d", newSizeW, newSizeH);
        if (chatBox.hasText)
        {
            // if the height of our new chatbox is
            // below 90 we can set the height
            if (newSizeH <= 90)
            {
                [chatBox scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
    
                // chatbox
                CGRect chatBoxFrame = chatBox.frame;
                NSInteger chatBoxH = chatBoxFrame.size.height;
                NSInteger chatBoxW = chatBoxFrame.size.width;
                NSLog(@"CHAT BOX SIZE : %d X %d", chatBoxW, chatBoxH);
                chatBoxFrame.size.height = newSizeH + 12;
                chatBox.frame = chatBoxFrame;
    
                // form view
                CGRect formFrame = viewForm.frame;
                NSInteger viewFormH = formFrame.size.height;
                NSLog(@"FORM VIEW HEIGHT : %d", viewFormH);
                formFrame.size.height = 30 + newSizeH;
                formFrame.origin.y = 199 - (newSizeH - 18);
                viewForm.frame = formFrame;
    
                // table view
                CGRect tableFrame = viewTable.frame;
                NSInteger viewTableH = tableFrame.size.height;
                NSLog(@"TABLE VIEW HEIGHT : %d", viewTableH);
                tableFrame.size.height = 199 - (newSizeH - 18);
                viewTable.frame = tableFrame;
            }
    
            // if our new height is greater than 90
            // sets not set the height or move things
            // around and enable scrolling
            if (newSizeH > 90)
            {
                chatBox.scrollEnabled = YES;
            }
        }
    }
    

    Once we are and the user presses the send button we want to do something with our text, the keyword will disappear and we want to reset our view back as they were. So how do we do that?

    - (IBAction)chatButtonClick:(id)sender{
        // hide the keyboard, we are done with it.
        [chatBox resignFirstResponder];
        chatBox.text = nil;
    
        // chatbox
        CGRect chatBoxFrame = chatBox.frame;
        chatBoxFrame.size.height = 30;
        chatBox.frame = chatBoxFrame;
        // form view
        CGRect formFrame = viewForm.frame;
        formFrame.size.height = 45;
        formFrame.origin.y = 415;
        viewForm.frame = formFrame;
    
        // table view
        CGRect tableFrame = viewTable.frame;
        tableFrame.size.height = 415;
        viewTable.frame = tableFrame;
    }
    

    The resignFirstResponder is going to hide the keyboard and then all we have to do is set the views and chatBox back to their original states.

    -(void) keyboardWillHide:(NSNotification *)note{
        // get keyboard size and loction
    
        CGRect keyboardBounds;
        [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds];
    
        // get the height since this is the main value that we need.
        NSInteger kbSizeH = keyboardBounds.size.height;
    
        // get a rect for the table/main frame
        CGRect tableFrame = viewTable.frame;
        tableFrame.size.height += kbSizeH;
    
        // get a rect for the form frame
        CGRect formFrame = viewForm.frame;
        formFrame.origin.y += kbSizeH;
    
        // animations settings
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:0.3f];
    
        // set views with new info
        viewTable.frame = tableFrame;
        viewForm.frame = formFrame;
    
        // commit animations
        [UIView commitAnimations];
    }
    

    And there you go, a textview that starts off as a single line and grows in size as the user enters text to a max size before becoming a scrolling textview.

    UITextField doesn’t let you to write more than one line… but you can use UITextView instead, and use the NSString -sizeWithFont function to understand how much space you need.

    like this:

    CGSize size = [yourTextView.text sizeWithFont:yourTextView.font];
    CGRect f = yourTextView.frame;
    f.size.height = ceil(size.width/f.size.width)*size.height
    yourTextView.frame = f;
    

    I didn’t tried this code, but I already used a code like that in the past.
    I hope my informations may be useful 🙂