NSUnderlineStyle
неправильный тип
Точно, но несколько бесполезно, документация объясняет, что ключ атрибута underlineStyle
принимает значение атрибута "NSNumber
, содержащее целое число".
Значением этого атрибута является объект NSNumber, содержащий
целое число. Это значение указывает, подчеркнут ли текст и
соответствует одной из констант, описанных в NSUnderlineStyle.
значение по умолчанию для этого атрибута - styleNone.
Многие читатели тянутся к NSUnderlineStyle
, щелкают по нему и находят список стилей, похожий на enum: single
, thick
, patternDash
, double
и т. Д. Это все кажется хорошим Быстрое решение. Читатель интуитивно понимает, что это перечисление должно указывать значение атрибута, и вводит код, показанный в вопросе выше.
Свойство rawValue
NSUnderlineStyle
обеспечивает правильный тип
NSUnderlineStyle
не является перечислением. Это структура, соответствующая протоколу OptionSet
. Протокол OptionSet
- это удобный, быстрый способ установки битов целого числа, где каждый бит представляет двоичное состояние. Структура NSUnderlineStyle
является оберткой вокруг этого целого числа. Его enum-подобные стили на самом деле являются статическими переменными в структуре, каждый из которых возвращает экземпляр NSUnderlineStyle
со встроенным целым числом, при этом только один из битов переворачивается, чтобы соответствовать желаемому стилю.
Словарь атрибутов
NSAttributedString
принимает буквально что угодно как значение, поэтому он с радостью принимает экземпляры NSUnderlineStyle
. Но TextKit, движок, который заставляет работать UITextView
и UILabel
, не знает, что делать с экземпляром NSUnderlineStyle
. Когда TextKit пытается отобразить атрибут underlineStyle
, ему требуется целое число, чтобы он мог определить правильный стиль, проверяя биты целого числа.
К счастью, есть простой способ получить это целое число. Свойство rawValue
NSUnderlineStyle
продает его. Таким образом, правильно работающая версия нашего фрагмента кода выглядит следующим образом:
let string = NSMutableAttributedString(string: "This is my string.")
string.addAttributes([.underlineStyle : NSUnderlineStyle.single.rawValue],
range: NSRange(location: 5, length: 2))
Единственная разница между этим кодом и кодом в вопросе заключается в добавлении ".rawValue" к "NSUnderlineStyle.single". И "is" подчеркнуто.
В качестве примечания, тип, продаваемый свойством rawValue
, - Int
, а не NSNumber
. Ссылка в документации на значение атрибута NSNumber
может сбить с толку. Под капотом для взаимодействия с ObjC NSAttributedString
оборачивает Int
внутри NSNumber
. Нет необходимости (или выгоды?) Явно включать Int
в NSNumber
.
Используйте метод OptionSet
union
для объединения подчеркнутых стилей
Мы можем объединить несколько стилей подчеркивания в составной стиль. На побитовом уровне это достигается путем принятия логического ИЛИ целых чисел, представляющих два стиля. Будучи OptionSet
, NSUnderlineStyle
предоставляет альтернативу Swifty. Метод union(_:)
для NSUnderlineStyle
выполняет логическое ИЛИ более простым языком. Как пример:
NSUnderlineStyle.double.union(.patternDot).rawValue
Этот код выдает Int
с соответствующими битами, а TextKit рисует очень красивую пунктирную двойную подчеркивание. Конечно, не все комбинации работают. NSAttributedString может принять все, но здравый смысл и механизм TextKit
в конечном итоге будут диктовать.