1

In my iOS keyboard extension, I have a function that moves the cursor backwards as follows:

(textDocumentProxy).adjustTextPositionByCharacterOffset(-1)

and displays the words right before the cursor in a UILabel using the textDocumentProxy.documentContextBeforeInput function provided by Apple. The problem is, whenever an emoji appears inside the label, it starts being separated as such: enter image description here

Is there any way of avoiding this? Does it have anything to do with me hardcoding the -1? I've tried using str.utf16.countbut that just doesn't scroll at all for some reason. Any help would be greatly appreciated.

Here's my question from a few months ago that never got answered

Community
  • 1
  • 1
cyril
  • 3,020
  • 6
  • 36
  • 61
  • 1
    If the old question never got answered it might be worth starting a bounty? Additionally I would recommend reading through this excellent answer on stack about characters in a string: http://stackoverflow.com/a/23397279/3723434 .The writer uses Cyrillic as an example of multi-byte strings, which is similar to emoji in its use. – trdavidson Apr 26 '16 at 02:23

1 Answers1

1

It appears that each offset will move the cursor by 16 bit and any characters with 32 bit will be cut in half. So the solution is for every 32 bit characters we move the cursor by 2 instead of 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)
}
Tũn
  • 11
  • 1
  • Hey this seems to work fine for some emoji but not all! i.e. it works for but fails for . Is there a way around this? I've upvoted your answer though! – cyril May 13 '16 at 21:53