6

Tło

Więc z iOS 6 UITextView można wziąć attributedString, która może być przydatna dla podświetlanie składni.UITextView attributedText i podświetlanie składni

Robię kilka wzorów regex w -textView:shouldChangeTextInRange:replacementText: i często potrzebuję zmienić kolor już wpisanego słowa. Nie widzę innych opcji niż resetowanie atrybutuTekst, co wymaga czasu.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 
{ 
    //A context will allow us to not call -attributedText on the textView, which is slow. 
    //Keep context up to date 
    [self.context replaceCharactersInRange:range withAttributedString:[[NSAttributedString alloc] initWithString:text attributes:self.textView.typingAttributes]]; 

    // […] 

    self.textView.scrollEnabled = FALSE; 

    [self.context setAttributes:self.defaultStyle range:NSMakeRange(0, self.context.length)]; 
    [self refresh]; //Runs regex-patterns in the context 
  textView.attributedText = self.context; 

    self.textView.selectedRange = NSMakeRange(range.location + text.length, 0); 
    self.textView.scrollEnabled = TRUE; 

    return FALSE; 
} 

ten biegnie okayish na symulatorze, ale na iPada 3 każdy -setAttributedText trwa kilka setek milisekund.

Złożyłem błąd do Apple, z prośbą o możliwość mutacji atrybutuText. Został oznaczony jako duplikat, więc nie widzę, co o tym mówią.

Pytanie

Im bardziej konkretne pytanie: Jak mogę zmienić kolor niektórych zakresach w UITextView, z dużym tekstem wielokolorowe, z dość dobrych wyników to zrobić w każdej shouldReplaceText...?

Im bardziej szeroka pytanie: Jak to zrobić podświetlanie składni z UITextView w iOS 6?

+0

Ja również próbuje zaznaczyć tekst jest mówione w mojej aplikacji głośników internetowej. Pomyślałem, że będę mógł to zrobić z łatwością z iOS6, ale nie mogłem znaleźć api, aby dynamicznie zmieniać kolor napisów w pewnym zakresie. Ustawianie pełnego przypisywanego tekstu za każdym razem zajmuje zbyt dużo czasu. –

+0

Złożyłem również zgłoszenie błędu do Apple. Potrzebujemy czegoś podobnego do tej metody. "textView_.attributedText addAttribute: wartość: zakres czcionek:" –

+0

Tak, ale założę się, że nigdy nie zobaczymy zmiennej wersji atrybutuText, ponieważ tekstView musi wiedzieć, kiedy ciąg znaków zostanie zmieniony. Mam nadzieję, że albo inteligentniejszy seter, albo przypisana wersja UITextInput '-replaceRange: withText:' –

Odpowiedz

0

Atrybutowe odpowiedniki tekstowe muszą być w obie strony do/z HTML, więc jest to naprawdę nieoptymalne dla implementacji podświetlania tekstu z podświetloną składnią. Na iOS 6 prawdopodobnie będziesz chciał używać CoreText bezpośrednio.

+0

Nie wiem dokładnie, jak działa HTML tekstViewView, ale można zmienić atrybuty tak łatwe, jak zastąpienie niektórych tekst w DOM i aktualizowanie tekstu textView, prawda? –

1

Napotkałem ten sam problem dla mojej aplikacji Zap-Guitar (No-Strings-Attached), w której pozwalam użytkownikom na wpisywanie/wklejanie/edytowanie własnych utworów, a aplikacja podświetla rozpoznane akordy.

Tak, to prawda, jabłko używa programu piszącego i analizatora html do wyświetlenia przypisanego tekstu. Wspaniałe wyjaśnienie tej sceny można znaleźć tutaj: http://www.cocoanetics.com/2012/12/uitextview-caught-with-trousers-down/

Jedynym rozwiązaniem, które znalazłem w tym problemie, nie jest użycie przypisanego tekstu, który jest przesadą dla podświetlania składni.

Zamiast tego powróciłem do starego dobrego UITextView z tekstem i dodałem przyciski do widoku tekstowego, w którym potrzebne było podświetlenie. Aby obliczyć ramki przycisków, skorzystałem z następującej odpowiedzi: How to find position or get rect of any word in textview and place buttons over that?

Zmniejszenie użycia procesora o 30% (podać lub odebrać).

Oto przydatny kategoria:

@implementation UITextView (WithButtons) 
- (CGRect)frameForTextRange:(NSRange)range { 
    UITextPosition *beginning = self.beginningOfDocument; 
    UITextPosition *start = [self positionFromPosition:beginning offset:range.location]; 
    UITextPosition *end = [self positionFromPosition:start offset:range.length]; 
    UITextRange *textRange = [self textRangeFromPosition:start toPosition:end]; 
    CGRect rect = [self firstRectForRange:textRange]; 
    return [self convertRect:rect fromView:self.textInputView]; 
} 

@end