ios - ¿Es posible obtener una lista de atributos y rangos para un NSMutableAttributedString?
uilabel nsattributedstring (7)
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)
}
En caso de que haya definido el texto attributedText
de la etiqueta.
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))
He creado un método que toma un NSAttributedString y estoy buscando crear dinámicamente una subvista y una etiqueta para colocar la cadena. Debido a que los atributos como la fuente y el tamaño deben determinarse para determinar correctamente el tamaño de la etiqueta, ¿debo determinar si es posible iterar a través de los valores y rangos que se han aplicado a la cadena atribuida?
Entiendo que podría pasar los atributos por separado, pero por motivos de reutilización, me gustaría poder pasar la menor cantidad posible de parámetros al método.
Apple espera que uses enumerateAttributesInRange:options:usingBlock:
El bloque que suministre recibirá los rangos y los atributos aplicables para ese rango.
Lo he usado en mi código para crear botones invisibles que se colocan detrás del texto para que actúe como un hipervínculo.
También puede usar enumerateAttribute:inRange:options:usingBlock:
si solo hay uno en el que está interesado, pero no se proporciona un medio camino donde pueda estar interesado en, por ejemplo, dos atributos pero no todos los atributos.
He modificado una de las respuestas con soluciones sugeridas para evitar recursiones infinitas y bloqueos de aplicaciones.
@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!])
}
}
}
Si necesita todos los atributos de la cadena en todo el rango, use este código:
NSDictionary *attributesFromString = [stringWithAttributes attributesAtIndex:0 longestEffectiveRange:nil inRange:NSMakeRange(0, stringWithAttributes.length)];
Swift 3:
// in case, that you have defined `attributedText` of label
var attributes = attributedText.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, attributedText.length))
...
Swift 4:
Si desea obtener los atributos para NSTextAttachment (solo cambie el valor del atributo si desea una fuente)
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)")
}
}
Los documentos de Apple tienen varios métodos para acceder a los atributos:
Para recuperar valores de atributos de cualquiera de los tipos de cadena atribuida, use cualquiera de estos métodos:
attributesAtIndex:effectiveRange:
attributesAtIndex:longestEffectiveRange:inRange:
attribute:atIndex:effectiveRange:
attribute:atIndex:longestEffectiveRange:inRange:
fontAttributesInRange:
rulerAttributesInRange: