Я создаю подкласс NSTextStorage
, чтобы выделить ссылки, и я прочитал столько, сколько I можете в теме. Все работает нормально, пока я не наберу символ ????
emoji.
Мой подкласс:
private let ims = NSMutableAttributedString()
override var string: String {
return ims.string
}
override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] {
return ims.attributesAtIndex(location, effectiveRange: range)
}
override func replaceCharactersInRange(range: NSRange, withString str: String) {
ims.replaceCharactersInRange(range, withString: str)
self.edited(.EditedCharacters, range: range, changeInLength:(str as NSString).length - range.length)
}
override func setAttributes(attrs: [String : AnyObject]?, range: NSRange) {
ims.setAttributes(attrs, range: range)
self.edited(.EditedAttributes, range: range, changeInLength: 0)
}
Ничего сложного. Затем при вводе печально известного персонажа он по какой-то случайной причине переключается на Courier New:
Сейчас придираюсь к персонажу ????
, есть и другие, вызывающие это безумие. Я запросил шрифт по мере ввода, и он идет из «Система»> «Apple Emoji»> «Courier New».
Я также попытался установить шрифт изнутри processEditing()
, что частично решает проблему, это приводит к добавлению дополнительного пробела (но не в симуляторе). И я жестко задаю значение == плохое.
Окончательный вопрос:
Что я делаю не так? Я не вижу этой проблемы с реализациями других людей, где, я уверен, разработчики создали подкласс NSTextStorage.
Примечание. Я могу подтвердить, что в демонстрационном приложении objc.io присутствует та же проблема.
processEditing()
- person Shawn Throop   schedule 21.06.2016processEditing
. По крайней мере, это не ломает смайлики. - person Nekto   schedule 21.06.2016fixAttributesInRange(range: NSRange)
— это место, где этот материал определяется в NSTextStorage, так что это, вероятно, лучшее место для обхода этого. К сожалению, простое удаление любых нераспознанных шрифтов не во всех случаях будет работать, так какfixAttributesInRange
также выполняет замену шрифта для неизвестных символов (как это делается для эмодзи). - person Archagon   schedule 12.09.2016fixAttributesInRange
) в шрифт эмодзи Apple (AppleColorEmoji). Это означает, что все, что напечатано после этого смайлика, также будет использовать этот шрифт (как и ожидалось с атрибутами NSAttributedString). Однако AppleColorEmoji не содержит символов для обычных букв, поэтому диапазон этих букв, в свою очередь, изменяется с AppleColorEmoji на моноширинный. Если бы только был способ указать NSAttributedString ограничить шрифт только определенным диапазоном и никогда не увеличивать его! - person Archagon   schedule 12.09.2016fixAttributes(in range: NSRange)
у меня не сработала. Я все еще печатаю_NSLayoutTreeLineFragmentRectForGlyphAtIndex invalid glyph index 1
в отладчике с эмодзи - person tettoffensive   schedule 21.04.2017processEditing()
я применяю эти атрибуты к значению диапазона, возвращаемомуparagraphRange(for: editedRange)
, до применения других атрибутов. В рамках init я присваиваю значение шрифта, созданное из API UIFontDescriptor, атрибуту defaultAttributes и черезdidSet
вызываюedited(_: range: changeInLength:)
, передавая.editedAttributes
для editedMask. - person Shawn Throop   schedule 21.04.2017