2009-02-09 4 views
30

J'ai un UIView et j'ajouter un UITextView modifiable à lui,UITextView défilement automatique vers le bas

UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(5, 5, 219, 47)]; 
[self addSubview:textView]; 
textView.font = [UIFont systemFontOfSize:14]; 

Quand je tape ça ne va pas vers le bas automatique. Quelqu'un a une idée?

Répondre

0

se trouve une solution

je mets la textview en vue et définir la vue à ClipToBounds = OUI puis-je mettre la textView à une hauteur de 70

qui a résolu le problème.

solution très étrange, mais cela fonctionne enfin :)

+0

Si 70 est inférieur à la hauteur d'origine de votre UITextView, alors il est écrêté à cette valeur probablement par coïncidence, c'est exactement ce qu'il faut pour que votre cas "défile automatiquement" jusqu'à la dernière ligne. C'est un peu trop hackish :) –

7

Je pense que vous aurez à faire

[textView scrollRangeToVisible:[textView selectedRange]]; 

dans textDidChange.

+0

non cela ne fait rien –

+0

hmm, étrange. pouvez-vous essayer [textView scrollRangeToVisible: NSMakeRange (textView.text.length, 0)]; –

+0

ne fonctionne pas non plus –

52

juste compris que vous devez utiliser une longueur> 0. Ie

NSRange range = NSMakeRange(textView.text.length - 1, 1); 
[textView scrollRangeToVisible:range]; 

a marché pour moi de toute façon.

+1

Merci, c'était utile. Vous devez également vérifier si textView.text.length> 0. –

+0

Notez que cela entraînera le déplacement de textView vers le bas. Ce n'est pas une bonne idée de le mettre dans textViewDidChange: delegate de UITextView; Si vous modifiez en haut de la vue texte, le texte défilera vers le bas, ce qui n'est pas ce à quoi s'attend l'utilisateur. –

+1

essayé différentes solutions, mais c'est celui qui a fonctionné comme un charme – gangt

11

Pour faire défiler jusqu'à la fin du tampon j'ai essayé

[textView scrollRangeToVisible:NSMakeRange([textView.text length]-1, 1)]; 

Mais rien ne se produisit. Au lieu de cela ceci fonctionne

textView.selectedRange = NSMakeRange(textView.text.length - 1, 0); 
0

Cela fonctionne:

- (void)textViewDidChange:(UITextView *)textView { 
    if (_moveToBottom) { 
     int y = textView.contentSize.height - textView.frameHeight + self.textView.contentInset.bottom + self.textView.contentInset.top; 
     if(y > 0) { 
      [textView setContentOffset:CGPointMake(0, y) animated:YES]; 
     } 
     _moveToBottom = NO; 
    } 
    else { 
     [textView scrollRangeToVisible:NSMakeRange([textView.text length]-1, 1)]; 
    } 
} 

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 
    if ([text isEqualToString:@"\n"] && range.location == [textView.text length]) { 
     _moveToBottom = YES; 
    } 
    return YES; 
} 
1

Utilisez contentOffset, il défilera automatiquement vers le bas

textView.contentOffset = CGPointMake(0, textView.contentSize.height - textView.frame.size.height); 
3

Lorsque vous ajoutez du texte à une zone de texte par programme, je trouve que je aussi nécessaire d'ajouter "[textView layoutIfNeeded]" pour configurer les choses avant que la nouvelle position de défilement puisse être calculée correctement.

par exemple:

[newString appendFormat:@"%@\n",addText]; 
textView.text = newString; 
[textView layoutIfNeeded]; 
NSRange range = NSMakeRange(textView.text.length - 2, 1); //I ignore the final carriage return, to avoid a blank line at the bottom 
[textView scrollRangeToVisible:range] 

Sans cet ajout la zone de texte ne parfois pas défiler, ou se défiler plusieurs lignes à chaque fois une seule ligne de données a été ajouté.

+0

Cela a fonctionné pour moi: '[textView layoutIfNeeded]; [textView scrollRangeToVisible: NSMakeRange (0, 0)]; ' – mehdok

2

Swift 2.2. Il fonctionne pour moi

func textViewDidChange(textView: UITextView) { 

    let bottomOffset = CGPointMake(0, textView.contentSize.height - textView.bounds.size.height) 
    textView.setContentOffset(bottomOffset, animated: true) 
} 
+0

Cela semble fonctionner lorsque UITextView est plus grand que son contenu, mais dès que le contenu dépasse la taille de l'écran, il ne défile plus pour moi. – lionello

0

J'ai trouvé que si le texte ajouté à la UITextView contenait des retours chariot, le textview ne défilent pas correctement.

J'ai ajouté la logique suivante pour permettre de calculer correctement les limites avant de faire défiler la plage.

BOOL autoscroll = NO; 

//I added a 10 px buffer here to allow for better detection as the textview is auto populated 
if (textView.contentOffset.y >= (textView.contentSize.height - textView.frame.size.height - 10)) 
{ 
    autoscroll = YES; 
} 

[textView setText:messageString]; 
[textView layoutSubviews]; 

if(autoscroll) { 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)),  dispatch_get_main_queue(), ^{ 
     [textView scrollRangeToVisible:NSMakeRange(textView.text.length - 1, 1)]; 
    }); 
}