2016-11-09 4 views
1

Ich habe eine UITextView mit vielen verschiedenen Wörtern nebeneinander. Wenn der Benutzer diesen Bildschirm betritt ich beginnen soll einige Worte hervorgehoben, zum Beispiel:Wie kann ich den Stil einiger Wörter in meinem UITextView einzeln in Swift ändern?

das erste, was er sieht, ist eine Wand aus Text:

one two three #four five six #seven eight nine ten 
eleven #twelve thirteen fourteen fifteen sixteen 
some other words #example test whatever #some thing 

dann, nach einer Sekunde, das Wort four würde Stil ändern (Farbe), so würde er sehen:

one two three #FOUR five six #seven eight nine ten 
eleven #twelve thirteen fourteen fifteen sixteen 
some other words #example test whatever #some thing 

dann, nach einer Sekunde, würde ein anderes Wort markiert (und kommen bereits farbige four):

one two three #FOUR five six #SEVEN eight nine ten 
eleven #twelve thirteen fourteen fifteen sixteen 
some other words #example test whatever #some thing 

und so weiter. So nach ein paar Sekunden Benutzer würde sehen:

one two three #FOUR five six #SEVEN eight nine ten 
eleven #TWELVE thirteen fourteen fifteen sixteen 
some other words #EXAMPLE test whatever #SOME thing 

und dann sollte der Text so bleiben. Wie kann ich das erreichen?

Ich dachte daran, Wörter durchzuschleifen und zu überprüfen, ob sie den vordefinierten Wörtern entsprechen, aber ich habe keine Ahnung, wie ich es beißen kann - können Sie mir dabei helfen?

===== EDIT

Also macht die Dinge einfacher für mich ich mit # Symbol markierten Wörter markieren entschieden.

Ich habe Erweiterung alle Wörter hervorzuheben, die mit # im Textview beginnen:

extension UITextView { 

func formatTextInTextView() { 
    self.isScrollEnabled = false 
    let selectedRange = self.selectedRange 
    let text = self.text 
    let font = UIFont(name: "AppleSDGothicNeo-Light", size: 16.0) 
    let titleDict: NSDictionary = [NSFontAttributeName: font!] 
    // This will give me an attributedString with the desired font 
    let attributedString = NSMutableAttributedString(string: text!, attributes: titleDict as! [String : AnyObject]) 
    let regex = try? NSRegularExpression(pattern: "#(\\w+)", options: []) 
    let matches = regex!.matches(in: text!, options: [], range: NSMakeRange(0, (text?.characters.count)!)) 
    for match in matches { 
     let matchRange = match.rangeAt(0) 

     let titleDict: NSDictionary = [NSForegroundColorAttributeName: orangeColor] 

     attributedString.addAttributes(titleDict as! [String : AnyObject], range: matchRange) 
    } 
    self.attributedText = attributedString 
    self.selectedRange = selectedRange 
    self.isScrollEnabled = true 
} 
} 

aber ich bin nicht sicher, wie jedes Wort mit Verzögerung von einer Sekunde

+0

Ihre Idee einer Schleife ist auf der richtigen Spur. Versuch etwas. Aktualisieren Sie Ihre Frage mit einem verwandten Code, der zumindest einige grundlegende Versuche zeigt. Beschreiben Sie klar, wofür Sie Hilfe benötigen. – rmaddy

+0

@maddy, ich habe meine Frage bearbeitet, danke, dass du darauf hingewiesen hast! – user3766930

+0

Dieser Code markiert alle Wörter auf einmal aufgrund des regulären Ausdrucks, den Sie verwenden. Sie benötigen eine Möglichkeit, um eine Liste (Array) von Wörtern zu erstellen, die Sie markieren möchten, und dann durch dieses Array zu iterieren. Für jedes Wort finden Sie dann alle Übereinstimmungen dieses einen Wortes. – rmaddy

Antwort

1

Verwenden Sie einen Timer separat zu markieren. Versteckte Übereinstimmungen in einer Eigenschaft. Verbergen Sie die nicht hervorgehobene attributierte Basiszeichenfolge in einer Eigenschaft. Lassen Sie nun Ihren Timer das erste Match markieren und rufen Sie sich in 1 Sekunde erneut auf, markieren Sie bis zum zweiten Match und wiederholen Sie, bis keine Matches mehr übrig sind.

func highlight (to index: Int = 0) { 
     guard index < matches.count else { 
      return 
     } 
     let titleDict: NSDictionary = [NSForegroundColorAttributeName: orangeColor] 
     let attributedString = NSMutableAttributedString(attributedString: storedAttributedString) 
     for i in 0..< index { 
      let matchRange = matches[i].rangeAt(0) 
      attributedString.addAttributes(titleDict as! [String : AnyObject], range: matchRange) 
     } 
     self.attributedText = attributedString 
     let _ = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in 
      self.highlight(to: index + 1) 
     } 
    } 
+0

danke Josh, ich habe deinen Code ausprobiert, aber es bringt mir viele Fehler, schau es dir an http://imgur.com/pOY6UYp weißt du, wie ich sie beheben könnte? – user3766930

+1

Ich habe im obigen Beispiel die fehlenden Argumentbezeichnungen für NSMutableAttributedString() und für die Schließung des Timers hinzugefügt. Ihr Fehler bei den Übereinstimmungen liegt darin, dass Übereinstimmungen eine Eigenschaft sein sollten, und sie sollte wie in Ihrem obigen Code definiert sein. Let matches = regex! .matches (in: text !, Optionen: [], range: NSMakeRange (0, (text?). characters.count)!)) was einen Typ von [NSTextCheckingResult] ergibt und nicht [String] –

+0

Danke Mann, zwei letzte Fragen though - diese Zeile 'self.attributedText = attributedString' wirft mir einen Fehler, dass 'attributedString' ein unaufgelöster Bezeichner ist :(und die zweite Sache - ich musste' if #available (iOS 10.0, *) {'zur Zeile mit Timer hinzufügen - und zur Zeit habe ich eine else block mit '// Fallback on friendly versions '- was ist die bestmögliche Option, um damit umzugehen? Kann ich nur irgendwie alle Wörter ohne einen Timer markieren? – user3766930

Verwandte Themen