65

我创建了一个采用 NSAttributedString 的方法,并且正在寻找动态创建子视图和标签以将字符串放入其中。因为需要确定字体和大小等属性才能正确确定标签的大小,所以我需要确定是否可以遍历已应用于属性字符串的值和范围?

我知道我可以单独传递属性,但为了可重用性,我希望能够向方法传递尽可能少的参数。

4

7 回答 7

98

斯威夫特 5 – 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)
}

如果您已经定义attributedText了标签。

斯威夫特 3

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

斯威夫特 2.2

var attributes = attributedText.attributesAtIndex(0,   
  longestEffectiveRange: nil, 
  inRange: NSMakeRange(0, attributedText.length)
)
于 2016-07-10T23:46:06.163 回答
29

Apple 希望您使用enumerateAttributesInRange:options:usingBlock:. 您提供的块将接收范围和适用于该范围的属性。

我在我的代码中使用它来创建放置在文本后面的不可见按钮,以便它充当超链接。

enumerateAttribute:inRange:options:usingBlock:如果只有一个您感兴趣,您也可以使用,但没有提供您可能感兴趣的中途之家,例如,两个属性但不是每个属性。

于 2013-11-07T19:04:29.950 回答
13

如果您需要整个范围内字符串中的所有属性,请使用以下代码:

NSDictionary *attributesFromString = [stringWithAttributes attributesAtIndex:0 longestEffectiveRange:nil inRange:NSMakeRange(0, stringWithAttributes.length)];

于 2016-08-31T18:44:06.063 回答
4

斯威夫特 3:

// in case, that you have defined `attributedText` of label
var attributes = attributedText.attributes(at: 0, longestEffectiveRange: nil, in: NSMakeRange(0, attributedText.length))
...
于 2017-02-15T13:01:12.903 回答
3

Apple 的 Docs有多种访问属性的方法:

要从任一类型的属性字符串中检索属性值,请使用以下任一方法:

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

于 2013-11-07T19:07:32.683 回答
3

斯威夫特 4:

如果要获取 NSTextAttachment 的属性(如果需要字体,只需更改属性值)

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)")
                            }
}
于 2017-12-28T19:25:17.650 回答
0

我已经用建议的修复修改了其中一个答案,以防止无限递归和应用程序崩溃。

@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!])
        }
    }
}
于 2018-04-17T14:47:09.270 回答