Как я могу обойти эмодзи, разбитые на символы?

В моем расширении клавиатуры iOS у меня есть функция, которая перемещает курсор назад следующим образом:

(textDocumentProxy).adjustTextPositionByCharacterOffset(-1)

и отображает слова прямо перед курсором в UILabel, используя функцию textDocumentProxy.documentContextBeforeInput, предоставленную Apple. Проблема в том, что всякий раз, когда эмодзи появляется внутри ярлыка, он начинает разделяться как таковой: введите здесь описание изображения

Есть ли способ избежать этого? Это имеет какое-то отношение к тому, что я жестко кодирую -1? Я пытался использовать str.utf16.count, но по какой-то причине он вообще не прокручивается. Любая помощь будет принята с благодарностью.

Вот мой вопрос, заданный несколько месяцев назад, который никогда не получил ответ


person cyril    schedule 26.04.2016    source источник
comment
Если на старый вопрос так и не ответили, возможно, стоит начать вознаграждение? Кроме того, я бы рекомендовал прочитать этот отличный ответ о стеке о символах в строке: stackoverflow.com/a/23397279/3723434 .В качестве примера многобайтовых строк автор использует кириллицу, которая по своему использованию похожа на эмодзи.   -  person trdavidson    schedule 26.04.2016


Ответы (1)


Похоже, что каждое смещение будет перемещать курсор на 16 бит, а любые символы с 32 битами будут обрезаны пополам. Таким образом, решение состоит в том, что для каждых 32-битных символов мы перемещаем курсор на 2 вместо 1.

func moveCursorBy(offset: Int, onProxy proxy: UITextDocumentProxy){
    var realOffset = 0
    if offset < 0, let text = proxy.documentContextBeforeInput {
        for uni in text.unicodeScalars.reverse().prefix(abs(offset)){
            realOffset -= uni.value > 0xFFFF ? 2 : 1
        }
    }
    else if offset > 0, let text = proxy.documentContextAfterInput{
        for uni in text.unicodeScalars.prefix(abs(offset)) {
            realOffset += uni.value > 0xFFFF ? 2 : 1
        }
    }
    else{
        realOffset = offset
    }
    proxy.adjustTextPositionByCharacterOffset(realOffset)
}
person Tũn    schedule 10.05.2016
comment
Эй, кажется, это работает нормально для некоторых смайликов, но не для всех! то есть это работает для ????, но не работает для ????????. Это можно обойти? Я проголосовал за ваш ответ, хотя! - person cyril; 14.05.2016