2009-02-09 3 views
30

Ho un UIView e io aggiungo un modificabile UITextView ad esso,UITextView scorrimento automatico giù

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

Quando digito che non va giù automatica. Qualcuno ha un'idea?

risposta

0

se ha trovato una soluzione

metto TextView in vista e impostare la vista ClipToBounds = YES Poi metto il textView ad un'altezza di 70

che risolto il problema.

molto strana soluzione, ma alla fine funziona :)

+0

Se 70 è inferiore all'altezza originale di UITextView, viene ritagliato su quel valore e probabilmente per coincidenza questo è esattamente ciò che serve per il tuo caso a "scorrere automaticamente" fino all'ultima riga. È un po 'troppo hacker :) –

7

penso che dovrete fare

[textView scrollRangeToVisible:[textView selectedRange]]; 

in textDidChange.

+0

no che non fa nulla –

+0

hmm, strano. puoi provare [textView scrollRangeToVisible: NSMakeRange (textView.text.length, 0)]; –

+0

non funziona –

52

appena capito che è necessario utilizzare una lunghezza> 0. Ie

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

lavorato per me in ogni modo.

+1

Grazie, questo è stato utile. È inoltre necessario verificare se textView.text.length> 0. –

+0

Notare che ciò causerà la visualizzazione di TextView verso il basso. Non è una buona idea metterlo nel testo di UITextViewViewDidChange: delegate; se si sta modificando nella parte superiore della vista testo, verrà spostato verso il basso, che non è quello che l'utente si aspetterebbe. –

+1

ha provato diverse soluzioni ma questa è quella che ha funzionato come un fascino – gangt

11

Per scorrere fino alla fine del buffer ho cercato

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

ma non accadde nulla. Invece questo funziona

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

Questo funziona:

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

Usa contentOffset, essa scorrerà automaticamente verso il basso

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

Quando si aggiunge testo a una casella di testo a livello di codice, ho ho trovato anche era necessario aggiungere "[textView layoutIfNeeded]" per impostare le cose prima che la nuova posizione di scorrimento potesse essere calcolata correttamente.

ad esempio:

[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] 

Senza questa aggiunta la casella di testo non a volte scorrere, o sarebbe scorrere diverse linee ogni volta che è stata aggiunta una singola riga di dati.

+0

Questo ha funzionato per me: '[textView layoutIfNeeded]; [textView scrollRangeToVisible: NSMakeRange (0, 0)]; ' – mehdok

2

Swift 2.2. Funziona per me

func textViewDidChange(textView: UITextView) { 

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

Sembra funzionare quando UITextView è più grande del suo contenuto, ma non appena il contenuto diventa più grande della dimensione sullo schermo, non scorre più per me. – lionello

0

ho scoperto che se il testo aggiunto alla UITextView conteneva ritorni a capo, quindi il TextView non sarebbe scorrere in modo corretto.

Ho aggiunto la logica come segue per consentire il calcolo corretto dei limiti prima di scorrere fino all'intervallo.

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