2017-02-01 1 views
0

J'ai un UITextView qui permet de sélectionner les mots du texte en tapant dessus. S'il est tapé, le mot est surligné en couleur en changeant l'attribut NSForegroundColor. En le tapant à nouveau, vous le désélectionnez en modifiant la couleur de la couleur de texte.Obtenir la couleur a changé les mots de la chaîne attribuée

Maintenant, je devrais connaître tous les mots sélectionnés dans le UITextView.

La première idée était de supprimer tout ce qui est un caractère spécial et diviser le texte à l'espace. Ensuite, vérifiez si l'attribut de couleur est égal à la couleur sélectionnée/surlignée de chaque mot séparé. Mais la chaîne attribuée ne permet pas de diviser un caractère ou de supprimer des composants. Le NSAttributedString non plus.

La deuxième idée consistait à enregistrer les plages des parties mises en surbrillance dans un tableau et à parcourir pour obtenir les parties mises en surbrillance. Mais cela semble un peu trop compliqué pour moi, d'autant plus que j'ai besoin de l'ordre correct des mots quand ils apparaissent qui n'est pas garanti avec un tableau, ajouter/enlever à chaque tap (Par exemple, disons que le texte est: "Ceci est un test »

Tap this -> index 0 
Tap test -> index 1 
Tap this -> test becomes index 0 
Tap this -> this becomes index 1 

alors l'ordre n'est plus bon.

je l'ai déjà compris comment obtenir la couleur d'une chaîne attribuée. Ce n'est pas le problème.

Comment puis-je itérer la chaîne attribuée et comprendre les mots qui ont changé de couleur ou quelle est la meilleure façon de résoudre ce problème?

Merci!

Salutations

Répondre

2

Vous pouvez itérer sur la chaîne attribué à la recherche de l'attribut de couleur.

Le code de suivi montre comment:

// This generates a test attributed string. 
// You actually want the attributedText property of your text view 
let str = NSMutableAttributedString(string: "This is a test of the following code") 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(0, 4)) 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(8, 1)) 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(15, 2)) 
print(str) 

Les impressions ci-dessus:

This{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} is { 
}a{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} test { 
}of{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} the following code{ 
} 

Ce code traite la chaîne attribuée. Toute plage de texte formatée avec une couleur de premier plan sera placée dans le tableau de mots.

var words = [String]() 
str.enumerateAttribute(NSForegroundColorAttributeName, in: NSMakeRange(0, str.length), options: []) { (value, range, stop) in 
    if value != nil { 
     let word = str.attributedSubstring(from: range).string 
     words.append(word) 
    } 
} 
print(words) 

Cette impression:

[ "Ce", "un", "de"]

+0

Merci, fonctionne comme un charme! –

0

Je vous suggère de créer une sorte de stockage pour les plages sélectionnées, alors sur cette gamme, vous pouvez personnaliser cette apparence de mots, et non l'inverse. Il vous permettra d'accéder aux mots sélectionnés à chaque fois sans vérifier les attributs du texte entier.

+0

Merci pour les suggestions. Comme je comprends pourquoi vous le suggérez, je m'en tiens à l'autre approche, car il n'est pas essentiel que mon projet réponde une fois sur toute la chaîne. –

0

Même si je suis d'accord avec Piotr que vous devez stocker le Ranges, pour répondre à votre question:

attributedString.enumerateAttributes(in: NSMakeRange(0, attributedString.length), options: []) { attributes, range, _ in 
    if let color = attributes[NSForegroundColorAttributeName] as? UIColor, 
     color == YOUR_HIGHLIGHT_COLOR { 
     let nString = attributedString.string as NSString 
     let word = nString.substring(with: range) 
     // Do what you want with the word 
    } 
}