Je crée une application qui a un UITextView
et un bouton.
Lorsque je clique sur le bouton, du texte sera ajouté dans le UITextView
.
Mais en cliquant sur le bouton, je ne veux pas faire défiler vers le bas du champ de texte pour que l'utilisateur puisse voir le dernier texte ajouté.
Comment faire défiler le UITextView
vers le bas?
J'ai essayé:
int numLines = LogTextView.contentSize.height / LogTextView.font.lineHeight+1;
NSLog(@"%d",numLines);
NSUInteger length = self.LogTextView.text.length;
self.LogTextView.selectedRange = NSMakeRange(0, length);
mais ça ne marchera pas ...
J'ai aussi essayé:
self.LogTextView.contentSize=CGSizeMake(length,0);
Vous pouvez utiliser le code suivant si vous parlez d'UITextView:
-(void)scrollTextViewToBottom:(UITextView *)textView {
if(textView.text.length > 0 ) {
NSRange bottom = NSMakeRange(textView.text.length -1, 1);
[textView scrollRangeToVisible:bottom];
}
}
Swift 4:
func scrollTextViewToBottom(textView: UITextView) {
if textView.text.count > 0 {
let location = textView.text.count - 1
let bottom = NSMakeRange(location, 1)
textView.scrollRangeToVisible(bottom)
}
}
Essayez ceci si vous avez un problème sur iOS 7 ou supérieur. Voir cette SO .
- (void)scrollTextViewToBottom:(UITextView *)textView {
NSRange range = NSMakeRange(textView.text.length, 0);
[textView scrollRangeToVisible:range];
// an iOS bug, see https://stackoverflow.com/a/20989956/971070
[textView setScrollEnabled:NO];
[textView setScrollEnabled:YES];
}
Avec Swift 3
let bottom = self.textView.contentSize.height - self.textView.bounds.size.height
self.textView.setContentOffset(CGPoint(x: 0, y: bottom), animated: true)
Vous devez implémenter une méthode déléguée. Le code ci-dessous vérifie si une nouvelle ligne a été entrée et, si c'est le cas, défile jusqu'au bas de la vue texte:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ([text isEqualToString:@"\n"]) {
textView.contentOffset = CGPointMake(0.0, textView.contentSize.height);
}
return YES;
}
Ça marche pour moi! :RÉ
CGPoint bottomOffset = CGPointMake(0, self.textView.contentSize.height - self.textView.bounds.size.height);
[self.description1 setContentOffset:bottomOffset animated:YES];
extension UITextView {
func simple_scrollToBottom() {
let textCount: Int = text.count
guard textCount >= 1 else { return }
scrollRangeToVisible(NSMakeRange(textCount - 1, 1))
}
}
// Usage
textView.simple_scrollToBottom()
Je n'ai pas pu trouver de solution sans utiliser NSRange
.
Faites une plage, en spécifiant l'encodage, jusqu'au dernier caractère, puis faites défiler jusqu'à cette plage Quelque chose d'autre que utf8 peut être approprié en fonction de votre contenu
let range = NSMakeRange(self.OutputTextView.text.lengthOfBytes(using: String.Encoding.utf8), 0);
self.OutputTextView.scrollRangeToVisible(range);
En tant qu'approche générique pour le défilement vers le bas, cela peut être fait sur un UIScrollView.
extension UIScrollView {
func scrollToBottom() {
let contentHeight = contentSize.height - frame.size.height
let contentoffsetY = contentHeight > 0 ? contentHeight : 0
setContentOffset(CGPoint(x: 0, y: contentoffsetY), animated: true)
}
}
Cela fonctionnera sur tous les descendants de UIScrollView comme UITextView, UITableView etc.
La version Swift de @ Hong Duan answer
func scrollTextViewToBottom(textView: UITextView) {
if textView.text.count > 0 {
let location = textView.text.count - 1
let bottom = NSMakeRange(location, 1)
textView.scrollRangeToVisible(bottom)
// an iOS bug, see https://stackoverflow.com/a/20989956/971070
textView.isScrollEnabled = false
textView.isScrollEnabled = true
}
}
textView.scrollRangeToVisible(NSRange(..<textView.text.endIndex, in: textView.text))
Cette solution fait quelques choses notables légèrement différentes:
String.Index
interface (probablement plus performante que par exemple .count
)PartialRangeUpTo
qui évite une position de début de plage explicite, réduisant le code à une ligne nette propre