iOS Keyboard Extensionでカーソルを移動させるにはadjustTextPosition(byCharacterOffset:Int)
を使います。ドキュメントにはバッチリ
To move the insertion point in the text input view, use the adjustTextPosition(byCharacterOffset:) method. For example, if you want to implement a forward delete action, move the insertion position forward by one character then delete backwards:
// Move the text insertion position forward 1 character (一文字分前に進める)
textDocumentProxy.adjustTextPosition(byCharacterOffset: 1)
と書いてありますが、罠です。なかなか気付きにくいところだと思うので共有しておきます。
「あいうえお」まではうまく動いていますが、漢字や絵文字に至ったあたりからどうも様子がおかしいですね。
解決方法
どうやらこのメソッドはutf16
とした時の文字数で「一文字分」を数えています。ということで、実行前に進行方向の文字をチェックして、それからadjustTextPosition
しましょう。
func getActualOffset(count: Int)->Int{
if count>0{
if let after = textDocumentProxy.documentContextAfterInput{
if after == ""{
return 1 //一文字前に改行がある場合、after==""となる。
}
let left = after.prefix(count)
return left.utf16.count
}else{
return 1
}
}else if count<0{
if let before = textDocumentProxy.documentContextBeforeInput{
let right = before.suffix(-count)
return -right.utf16.count
}else{
return -1
}
}else{
return 0
}
}
let offset = getActualOffset(count: 1) //正確なoffsetを取得する
textDocumentProxy.adjustTextPosition(byCharacterOffset: offset) //実行する
気付きづらいところに潜んでいる落とし穴なので、くれぐれもお気をつけください。