Можно ли получить список атрибутов и диапазонов для NSMutableAttributedString?
Я создал метод, который принимает NSAttributedString, и я ищу, чтобы динамически создать подвид и метку, чтобы поместить строку. Поскольку атрибуты, такие как шрифт и размер, должны быть определены, чтобы правильно определить размер метки, мне нужно определить, можно ли перебирать значения и диапазоны, которые были применены к приписываемой строке?
Я понимаю, что могу передавать атрибуты отдельно, но для удобства повторного использования я хотел бы иметь возможность передайте методу как можно меньше параметров.
7 ответов:
Apple ожидает, что вы будете использовать
enumerateAttributesInRange:options:usingBlock:
. Блок, который вы предоставляете, получит диапазоны и атрибуты, применимые для этого диапазона.Я использовал это в своем коде для создания невидимых кнопок, которые помещаются за текстом, чтобы он действовал как гиперссылка.
Вы также можете использовать
enumerateAttribute:inRange:options:usingBlock:
Если есть только один, который вас интересует, но нет промежуточного дома, где вы могли бы быть заинтересованы, скажем, в двух атрибутах, но не в каждом атрибуте.
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) }
В случае, если вы определили
attributedText
метки.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))
Если вам нужны все атрибуты из строки во всем диапазоне, используйте следующий код:
NSDictionary *attributesFromString = [stringWithAttributes attributesAtIndex:0 longestEffectiveRange:nil inRange:NSMakeRange(0, stringWithAttributes.length)];
Документы Apple имеют ряд методов для доступа к атрибутам:
Чтобы получить значения атрибутов из любого типа приписываемой строки, используйте любой из следующих методов:
attributesAtIndex:effectiveRange:
attributesAtIndex:longestEffectiveRange:inRange:
attribute:atIndex:effectiveRange:
attribute:atIndex:longestEffectiveRange:inRange:
fontAttributesInRange:
rulerAttributesInRange:
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:
Если вы хотите получить атрибуты для 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)") } }
Я изменил один из ответов с помощью предложенных исправлений, чтобы предотвратить бесконечную рекурсию и сбои приложений.
@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!]) } } }