Change in UITextFieldDelegate shouldChangeCharactersIn range.location behavior for Japanese input in iOS 26 with increased value

This problem occurs only when using the Japanese keyboard.

After typing ""あい"" into a text field and pressing Enter, insert ""う"" between ""あ"" and ""い"".

As a result, the displayed text becomes ""あううい"".

Text field: ""あい"" → ""あううい""

The range values at this point: range.location = 2

range.length = 2

・Behavior in iOS versions before 26

After typing ""あい"" into a text field and pressing Enter, insert ""う"" between ""あ"" and ""い"".

As a result, the displayed text becomes ""あうい"".

Text field: ""あい"" → ""あうい""

The range values at this point: range.location = 1

range.length = 1

The following source code can be used to reproduce the issue. mainApp (displaying a UIKit ViewController from SwiftUI)

import SwiftUI
import UIKit

struct ViewControllerWrapper: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> ViewController {
return ViewController()
}
func updateUIViewController(_ uiViewController: ViewController, context: Context) {}
}

@main
struct konnitihaApp: App {
var body: some Scene {
WindowGroup {
ViewControllerWrapper() // UIKitのViewControllerを表示
}
}
}


ViewController

import UIKit


class ViewController: UIViewController, UITextFieldDelegate {
let textField = UITextField()
let displayLabel = UILabel()
// 追加で管理するプロパティ
var replacementText: String = ""
var textInsertLocation: Int = 0
var textSelectedLength: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// UITextFieldの設定
textField.borderStyle = .roundedRect
textField.placeholder = ""
textField.delegate = self
textField.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(textField)

// UILabelの設定
displayLabel.text = ""
displayLabel.layer.borderWidth = 2
displayLabel.layer.borderColor = UIColor.blue.cgColor
displayLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(displayLabel)

// レイアウト
NSLayoutConstraint.activate([
textField.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40),
textField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
textField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
textField.heightAnchor.constraint(equalToConstant: 40),

//label
displayLabel.topAnchor.constraint(equalTo: textField.bottomAnchor, constant: 500),
displayLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
displayLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
displayLabel.heightAnchor.constraint(equalToConstant: 40),

])
}
// UITextFieldDelegate
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
self.replacementText = string
self.textInsertLocation = range.location
self.textSelectedLength = range.length
print("rangeは",range)
// ラベルに最新の文字列を反映
if let text = textField.text, let textRange = Range(range, in: text) {
let updatedText = text.replacingCharacters(in: textRange, with: string)
if textField == self.textField {

displayLabel.text = updatedText
}
}
return true
}
}
Change in UITextFieldDelegate shouldChangeCharactersIn range.location behavior for Japanese input in iOS 26 with increased value
 
 
Q