web-dev-qa-db-fra.com

Est-il possible d'obtenir une liste d'attributs et de plages pour un NSMutableAttributedString?

J'ai créé une méthode qui prend un NSAttributedString et je cherche à créer dynamiquement une sous-vue et un libellé dans lequel insérer la chaîne. Parce que des attributs tels que la police et la taille doivent être déterminés pour déterminer correctement la taille de l'étiquette, je dois déterminer s'il est possible d'effectuer une itération à travers les valeurs et les plages appliquées à la chaîne attribuée. 

Je comprends que je pourrais transmettre les attributs séparément, mais pour des raisons de réutilisabilité, j'aimerais pouvoir transmettre le moins de paramètres possible à la méthode.

33
propstm

Apple s'attend à ce que vous utilisiez enumerateAttributesInRange:options:usingBlock: . Le bloc que vous fournissez recevra des plages et les attributs applicables à cette plage.

Je l'ai utilisé dans mon code pour créer des boutons invisibles placés derrière le texte afin qu'il agisse comme un lien hypertexte.

Vous pouvez également utiliser enumerateAttribute:inRange:options:usingBlock: s'il n'y en a qu'un qui vous intéresse, mais aucune maison de transition n'est fournie où vous pourriez être intéressé, par exemple, à deux attributs, mais pas à chaque attribut.

20
Tommy

Swift 4

let attributedText = NSAttributedString(string: "Hello, playground", attributes: [
    .foregroundColor: UIColor.red, 
    .backgroundColor: UIColor.green, 
    .ligature: 1, 
    .strikethroughStyle: 1
])

// retrieve attributes
let attributes = attributedText.attributes(at: 0, effectiveRange: nil)

// iterate each attribute
for attr in attributes {
    print(attr.key, attr.value)
}

Si vous avez défini attributedText of label.

Swift 3

var attributes = attributedText.attributes(at: 0, longestEffectiveRange: nil, in: NSRange(location: 0, length: attributedText.length))

Swift 2.2

var attributes = attributedText.attributesAtIndex(0, longestEffectiveRange: nil, inRange: NSMakeRange(0, attributedText.length))
45
dimpiax

La documentation d'Apple dispose d'un certain nombre de méthodes pour accéder aux attributs:

Pour récupérer les valeurs d'attribut de l'un ou l'autre type de chaîne attribuée, utilisez l'une des méthodes suivantes:

attributesAtIndex:effectiveRange:attributesAtIndex:longestEffectiveRange:inRange:attribute:atIndex:effectiveRange:attribute:atIndex:longestEffectiveRange:inRange:fontAttributesInRange:rulerAttributesInRange:

3
paulrehkugler

Swift 3:

// in case, that you have defined `attributedText` of label
var attributes = attributedText.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, attributedText.length))
...
3
Trein

Swift 4:

Si vous voulez obtenir les attributs pour NSTextAttachment (changez simplement la valeur de l'attribut si vous voulez la police)

commentTextView.attributedText.enumerateAttribute(NSAttachmentAttributeName,
                        in:NSMakeRange(0, commentTextView.attributedText.length),
                        options:.longestEffectiveRangeNotRequired) {
                        value, range, stop in
                            if let attachment = value as? NSTextAttachment {
                                print("GOT AN ATTACHMENT! for comment at \(indexPath.row)")
                            }
}
1
Josh O'Connor

J'ai modifié l'une des réponses avec les corrections suggérées pour éviter une récursion infinie et des plantages de l'application. 

@IBDesignable
extension UITextField{

    @IBInspectable var placeHolderColor: UIColor? {
        get {
            if let color = self.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor {
                return color
            }
            return nil
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[.foregroundColor: newValue!])
        }
    }
}
0
Michał Ziobro