2013-05-23 33 views
12

Ho uno UITextView e quando l'utente inserisce del testo in esso, voglio formattare il testo al volo. Qualcosa come l'evidenziazione della sintassi ...Sostituisci testo UITextViews con stringa attribuita

Per questo mi piacerebbe utilizzare UITextView ...

tutto funziona bene aspettarsi un problema: prendo il testo dal punto di vista del testo e fa un NSAttributedString da esso. Apporto alcune modifiche a questa stringa attribuita e la reimposta come textView.attributedText.

Questo succede ogni volta che l'utente digita. Quindi devo ricordare lo selectedTextRange prima della modifica allo attributedText e reimpostarlo in seguito in modo che l'utente possa continuare a digitare nel punto in cui stava scrivendo prima. L'unico problema è che una volta che il testo è sufficientemente lungo da richiedere lo scorrimento, lo UITextView inizierà ora a scorrere verso l'alto se scrivo lentamente.

Ecco alcuni esempi di codice:

- (void)formatTextInTextView:(UITextView *)textView 
{ 
    NSRange selectedRange = textView.selectedRange; 
    NSString *text = textView.text; 

    // This will give me an attributedString with the base text-style 
    NSMutableAttributedString *attributedString = [self attributedStringFromString:text]; 

    NSError *error = nil; 
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error]; 
    NSArray *matches = [regex matchesInString:text 
            options:0 
             range:NSMakeRange(0, text.length)]; 

    for (NSTextCheckingResult *match in matches) 
    { 
    NSRange matchRange = [match rangeAtIndex:0]; 
    [attributedString addAttribute:NSForegroundColorAttributeName 
          value:[UIColor redColor] 
          range:matchRange]; 
    } 

    textView.attributedText = attributedString; 
    textView.selectedRange = selectedRange; 
} 

C'è qualche soluzione senza utilizzare direttamente CoreText? Mi piace l'abilità di UITextView s per selezionare il testo e così via ....

+1

@ NANNAV Grazie per i tuoi sforzi per migliorare SO modificando i post. Tuttavia, [non c'è davvero alcun motivo] (http://meta.stackexchange.com/q/158564/169503) per l'enfasi arbitraria arbitraria che sembri [a] (http://stackoverflow.com/review/suggested-edits/ 2242818) [introduce] (http://stackoverflow.com/review/suggested-edits/2247096) [in] (http://stackoverflow.com/review/suggested-edits/2248401) [varie] (http: // stackoverflow.com/review/suggested-edits/2248276) [post] (http://stackoverflow.com/review/suggested-edits/2247183). Introduce solo rumore e può effettivamente essere considerato attivamente dannoso. –

risposta

33

Non sono sicuro che questa sia la soluzione corretta, ma funziona.
basta disabilitare lo scorrimento prima della formattazione di testo e abilitarla dopo la formattazione

- (void)formatTextInTextView:(UITextView *)textView 
{ 
    textView.scrollEnabled = NO; 
    NSRange selectedRange = textView.selectedRange; 
    NSString *text = textView.text; 

    // This will give me an attributedString with the base text-style 
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text]; 

    NSError *error = nil; 
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"#(\\w+)" options:0 error:&error]; 
    NSArray *matches = [regex matchesInString:text 
             options:0 
             range:NSMakeRange(0, text.length)]; 

    for (NSTextCheckingResult *match in matches) 
    { 
     NSRange matchRange = [match rangeAtIndex:0]; 
     [attributedString addAttribute:NSForegroundColorAttributeName 
           value:[UIColor redColor] 
           range:matchRange]; 
    } 

    textView.attributedText = attributedString; 
    textView.selectedRange = selectedRange; 
    textView.scrollEnabled = YES; 
} 
+0

Grazie per la tua risposta !!! :) Nel frattempo ho trovato un'altra soluzione ... Ho appena sottoclasse UITextView e sovrascritto 'scrollRectToVisible: animated:' e lo faccio chiamare super senza animazioni ... La tua soluzione sembra un po 'più fluida :) Ancora, molte grazie! – Georg

+0

great .......... – svmrajesh

+0

Grazie per la risposta. Mi ha dato un'idea per risolvere il mio problema. – Karun

0

Swift 2.0:

let myDisplayTxt:String = "Test String" 

    let string: NSMutableAttributedString = NSMutableAttributedString(string: self.myDisplayTxt) 
    string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSMakeRange(0, 5)) 
    string.addAttribute(String(kCTForegroundColorAttributeName), value: UIColor.redColor().CGColor as AnyObject, range: NSMakeRange(0, 5)) 

    self.sampleTextView.attributedText = string 
4

Usato Sergeys di me rispondere e portato a Swift 2:

func formatTextInTextView(textView: UITextView) { 
    textView.scrollEnabled = false 
    let selectedRange = textView.selectedRange 
    let text = textView.text 

    // This will give me an attributedString with the base text-style 
    let attributedString = NSMutableAttributedString(string: text) 

    let regex = try? NSRegularExpression(pattern: "#(\\w+)", options: []) 
    let matches = regex!.matchesInString(text, options: [], range: NSMakeRange(0, text.characters.count)) 

    for match in matches { 
     let matchRange = match.rangeAtIndex(0) 
     attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: matchRange) 
    } 

    textView.attributedText = attributedString 
    textView.selectedRange = selectedRange 
    textView.scrollEnabled = true 
} 
+0

Quando chiamo questo metodo? In realtà voglio lo stesso come il tuo codice ma come collegamento. Puoi condividere quel codice. –