web-dev-qa-db-fra.com

Objectif C: Comment créer un UITextField multi-lignes?

Duplicata possible:
Comment créer un UITextfield multiligne?

Comment puis-je implémenter un champ de texte sur plusieurs lignes comme ce que je vois dans l'application de messagerie iPhone?

enter image description here

Il semble qu'une fois que la longueur de l'entrée dépasse la longueur, une deuxième ligne sera automatiquement créée.

EDIT: mis à jour pour clarifier mes défis dans l'utilisation d'un UITextView

Pour moi, je voudrais modéliser la sensation et l'apparence de l'UITextView comme indiqué ci-dessous. Je ne sais pas comment je peux le faire avec UITextView comme suggéré. Par exemple

1) Comment développer la boîte dynamiquement si mon texte doit déborder à la ligne suivante

2) Comment ajouter la bordure et le style comme indiqué ci-dessous

3) Comment attacher la zone de texte juste au-dessus du clavier (au lieu de dans la vue)

Je sais qu'Instagram a cela aussi, si quelqu'un peut me diriger dans la bonne direction, ce sera génial. Merci d'avance

enter image description here

24
Zhen

Vérifiez ces réponses:

Comment créer un UITextfield multiligne?

Comment créer un UITextfield multiligne?

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

Et essayez définitivement Three2 qui est une excellente bibliothèque utilisée dans de nombreuses applications comme Facebook.


Edit: Ajout d'un extrait du blog de BrettSchumann

#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>

Cela fait et pendant que nous mettons tout en place, allons-y et ajoutons nos articles à notre fichier principal (.m) en même temps sans oublier de les désallouer également.

@synthesize viewTable;
@synthesize viewForm;
@synthesize chatBox;
@synthesize chatButton;

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

Dans la méthode (void) viewDidLoad, nous devons ajouter des observateurs de notification afin de voir quand le clavier est affiché ou masqué et lorsque l'utilisateur appuie sur une touche du clavier.

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

Lorsque le focus est défini sur l'affichage de texte, le clavier s'affiche. Étant donné que la vue de texte et les boutons sont tous deux dans la vue inférieure de l'écran, le clavier va remonter et les parcourir. Donc, ce que nous voulons faire, c'est ajuster la hauteur de viewTable et la position de viewForm. Nous le faisons dans la méthode suivante.

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

Maintenant que le clavier est affiché et que nos vues ont été ajustées, nous voulons capturer le texte que l'utilisateur entre et voir si nous devons apporter des ajustements à la chatBox. Heureusement pour nous, nous pouvons utiliser l'objet CGSize, lui passer du texte et dire à l'objet quelle taille nous voudrions contraindre le texte vers et à partir de laquelle nous pouvons calculer obtenir la hauteur. La ligne varie avec la taille de la police et la largeur de votre objet CGSize variera avec la largeur de votre UITextview, vous devrez donc expérimenter un peu. La valeur de 12 utilisée dans le code ci-dessous est la différence de hauteur entre la hauteur de départ de ma chatBox et la hauteur de ligne en fonction de la police que j'ai définie.

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

Une fois que nous sommes et que l'utilisateur appuie sur le bouton d'envoi, nous voulons faire quelque chose avec notre texte, le mot-clé disparaîtra et nous voulons réinitialiser notre vue telle qu'elle était. Alors, comment on fait ça?

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

Le resignFirstResponder va cacher le clavier et ensuite tout ce que nous avons à faire est de remettre les vues et chatBox à leurs états d'origine.

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

Et voilà, une vue de texte qui commence comme une seule ligne et augmente en taille lorsque l'utilisateur entre du texte à une taille maximale avant de devenir une vue de texte défilante.

28
Nicolas S

UITextField ne vous permet pas d'écrire plus d'une ligne ... mais vous pouvez utiliser UITextView à la place et utiliser le NSString -sizeWithFont fonction pour comprendre l'espace dont vous avez besoin.

comme ça:

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;

Je n'ai pas essayé ce code, mais j'ai déjà utilisé un code comme ça dans le passé. J'espère que mes informations pourront être utiles :)

23
mt81