Я показываю текст, который может содержать emoji с использованием метода NSAttributedString
drawInRect(rect: CGRect)
. Так как я хочу, чтобы обнаружить краны по тексту я использую следующий метод, чтобы увидеть, какой символ был постучали:NSLayoutManager, boundingRectForGlyphRange и emoji
let textStorage = NSTextStorage(attributedString: attributedString)
let layoutManager = NSLayoutManager()
layoutManager.usesFontLeading = true
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: containerSize)
layoutManager.addTextContainer(textContainer)
textContainer.lineFragmentPadding = 0.0
layoutManager.ensureLayoutForTextContainer(textContainer)
let tappedIndex = layoutManager.characterIndexForPoint(point,
inTextContainer: textContainer,
fractionOfDistanceBetweenInsertionPoints: nil)
Это дает правильный индекс, что я могу работать с тем, пока я не начинаю добавлять смайлик к тексту. Как только emoji добавляется, начинается смещение для обнаружения. Это заставило меня взглянуть на ограничивающие прямоугольники глифов, которые я искал. Я заметил, что ограничивающие прямоугольники эможи слишком велики. Я создал следующий тест, чтобы проверить разницу:
let emojiText = ""
let font = UIFont.systemFontOfSize(20.0)
let containerSize = CGSize(width: 300.0, height: 20000.0)
let attributedString = NSAttributedString(string: emojiText, attributes: [NSFontAttributeName: font])
let textStorage = NSTextStorage(attributedString: attributedString)
let layoutManager = NSLayoutManager()
layoutManager.usesFontLeading = true
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: containerSize)
layoutManager.addTextContainer(textContainer)
textContainer.lineFragmentPadding = 0.0
layoutManager.ensureLayoutForTextContainer(textContainer)
let glyphRect = layoutManager.boundingRectForGlyphRange(NSRange(location: 0, length: attributedString.length), inTextContainer: textContainer)
let boundingRect = attributedString.boundingRectWithSize(containerSize, options:[.UsesLineFragmentOrigin, .UsesFontLeading], context: nil)
Выполнение этого кода привела следующие CGRect
S:
glyphRect = (0.0, 0.0, 23.0, 28.875)
boundingRect = (0.0, 0.0, 23.0, 23.8671875)
Что это означает, что эти два метода дают два совершенно разных размеров! Это не проблема, но «офсетные» стеки с большим количеством строк.
Я поставил фиолетовый фон для характера characterIndexForPoint
дал мне, дал прямоугольник из boundingRectForGlyphRange
зеленый контур и желтая точка является фактическим taplocation. Обратите внимание, что зеленый прямоугольник хорошо сочетается с другим персонажем, однако это не является признаком того, что происходит, поскольку в этом конкретном случае это происходит просто.
Я пропустил что-то очевидное или это проблема в iOS?