2013-05-07 12 views
11

Ich versuche zu ermöglichen, verschiedene Arten von Text in eine UITextView getippt werden, ein bisschen wie ein Texteditor mit einfachen Attributen wie fett oder kursiv. Ich verstehe, indem ich die Eigenschaft attributedText des textView verwende, kann ich Attribute auf bestimmte Bereiche des Textes anwenden. Das ist nett, aber ich würde gerne in der Lage sein, attributierten Text in die textView einzutippen, die durch eine Schaltfläche (wie die Eingabe von fettem Text) umgeschaltet werden würde.Wie kann NSAttributedString Text in eine UITextView eingegeben werden?

Hier ist, was ich gedacht habe von so weit:

mir die Methode -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text UITextView Delegaten verwendet habe das text Argument zu nehmen, und ändern Sie es mit Attributen durch eine NSAttributedString mit dem gleichen Text zu erstellen. Erstellen Sie dann einen NSMutableAttributedString, der eine Kopie des attributedText von textView ist. Fügen Sie die beiden mithilfe von appendAttributedString an, und legen Sie dann die Eigenschaft attributedText von textView auf den resultierenden attributedString fest.

Hier ist der Code:

-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 

    if (self.boldPressed) { 

     UIFont *boldFont = [UIFont boldSystemFontOfSize:self.textView.font.pointSize]; 
     NSDictionary *boldAttr = [NSDictionary dictionaryWithObject:boldFont forKey:NSFontAttributeName]; 
     NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc]initWithString:text attributes:boldAttr]; 
     NSMutableAttributedString *textViewText = [[NSMutableAttributedString alloc]initWithAttributedString:textView.attributedText]; 
     [textViewText appendAttributedString:attributedText]; 
     textView.attributedText = textViewText; 

      return NO; 
     } 
    return YES;     
} 

Mit dem Textviews attributedText ein Zeichen jedes Mal zurückgesetzt werden typisiert ist wie ein bisschen viel für eine einfache Aktion scheint. Nicht nur das, aber es funktioniert nicht richtig. Hier ist, wie es aussieht, wenn das Attribut fett aktiviert ist:

attributedText issues

Es gibt zwei Probleme mit diesem. Am offensichtlichsten ist es, wie jeder neue Charakter auf eine neue Linie gesetzt wird. Was aber auch merkwürdig ist, ist, dass der Einfügepunkt immer am allerersten Index des Textes in der Textansicht liegt (nur wenn Fett aktiviert ist, aber das Fettzeichen in eine neue Zeile eingefügt wird). Wenn Sie also Fettdruck aktivieren und dann fett abschalten, wird die Eingabe vor dem gesamten vorhandenen Text fortgesetzt.

Ich bin nicht sicher, warum diese Fehler passieren. Ich denke auch nicht, dass meine Lösung sehr effizient ist, aber ich kann mir keine andere Art vorstellen, sie umzusetzen.

+1

Dies sollte arbeiten, und ich denke, daß seine so gut, wie du es finden wirst. Können Sie einige Protokollnachrichten hinzufügen? Warum schreiben Sie nicht immer den attributierten String - geben Sie niemals YES zurück. Sie könnten einen Schatten-attributierten String haben, den Sie pflegen, und ihn immer in dieser Delegate-Methode festlegen, anstatt reguläre und attributierte Strings zu mischen. Wenn das fehlschlägt, lade eine Demo-App mit diesem Code hoch und jemand (wie ich) wird es sich ansehen. Ich bin zu 99% sicher, dass Sie das zur Arbeit bringen können (aber ich habe das nicht genau selbst gemacht). –

+0

Stellt sich heraus, dass die Eigenschaft 'typingAttributes' verwendet werden muss, wie Sie in der anderen Antwort sehen können. Das Hinzufügen einiger Protokollnachrichten ergab mehr Fragen als Antworten, da alle NSAttributedStrings, die an den attributeText von textView angehängt wurden, immer zu einer neuen Zeile gehen würden. Dies führt mich zu dem Schluss, dass dies in der Methode 'shouldChangeTextInRange' nicht möglich ist (daher die setTypingAttributes-Eigenschaft).Immer noch nicht sicher, warum, aber das Festlegen der 'typingAttributes' scheint in beiden Fällen eine viel elegantere Lösung zu sein. – Joe

+0

Hah - deshalb hat Rob Napier 70K Punkte! Froh, dass du eine Lösung gefunden hast - ich war mir sicher, dass es eine gab! –

Antwort

28

Dies ist, was setTypingAttributes: ist für. Setzen Sie dies auf Ihr Attributwörterbuch, wenn der Benutzer eine Ihrer Attributschaltflächen drückt und neue Zeichen die angeforderten Attribute übernehmen.

+0

Danke, hatte keine Ahnung, dass es existiert. Wie würden Sie das Attribut entfernen, wenn Sie es nicht mehr verwenden möchten? Ich habe versucht, die typingAttributes -Eigenschaft auf ein leeres Wörterbuch zu setzen, aber das entfernte alle anderen Attribute wie die Schriftgröße. Die Eigenschaft ist nicht veränderbar, daher kann das zuletzt hinzugefügte Attribut nicht entfernt werden. – Joe

+0

Machen Sie eine "mutableCopy" des aktuellen Wertes. Ändern Sie es und weisen Sie es erneut zu. –

+0

Ah, hab es. Sehr geschätzt. – Joe

3

Hier sind Beispielcodes, dies zu tun, wenn Sie Beispiele gesucht werden

Swift 3,0

var attributes = textField.typingAttributes 
attributes["\(NSForegroundColorAttributeName)"] = UIColor.red 
textField.typingAttributes = attributes 

Objective-C

NSMutableDictionary* attributes = [textField.typingAttributes mutableCopy]; 
attributes[NSForegroundColorAttributeName] = [UIColor redColor]; 
textField.typingAttributes = attributes; 
Verwandte Themen