I just tested with your new code and do not get the error.
Log shows:
input: changed from '' to '1'
input: changed from '1' to '12'
Moving cursor from 2[any]
Moved to 4[utf8]
input: changed from '12' to '12×'
input: changed from '12×' to '12×3'
input: changed from '12×3' to '12×34'
I run Xcode 16.4 on MacOS 15.5 (24F74) and iOS 18.4 simulator. Same with 18.5 simulator. Use hardware keyboard.
With simulator virtual keyboard (on device simulator), log is different:
input: changed from '' to '1'
input: changed from '1' to '12'
input: changed from '12' to '12*'
input: changed from '12*' to '12*3'
input: changed from '12*3' to '12*34'
No more move log, and no change from * to x.
So I added a print:
func handleKeyPress(_ keyPress: KeyPress) -> KeyPress.Result {
print(keyPress.key.character.unicodeScalars)
if (keyPress.key.character == "*") {
insertAtCursor(text: "×")
moveCursor(offset: 1)
return KeyPress.Result.handled
}
return KeyPress.Result.ignored
}
handleKeyPress is not called with virtual keyboard on simulator.
But it is with the hardware keyboard:
1
input: changed from '' to '1'
2
input: changed from '1' to '12'
*
Moving cursor from 2[any]
Moved to 4[utf8]
input: changed from '12' to '12×'
3
input: changed from '12×' to '12×3'
4
input: changed from '12×3' to '12×34'
So I added another log:
var body: some View {
VStack {
TextField("Type 12*34", text: $input, selection: $selection)
.onKeyPress(action: {keyPress in
print("onKeyPress", keyPress.key.character.unicodeScalars)
return handleKeyPress(keyPress)
})
.onChange(of: input) { oldValue, newValue in
print("input: changed from '\(oldValue)' to '\(newValue)'")
}
Text("Selection: \(selectionAsString())")
}.padding()
}
func handleKeyPress(_ keyPress: KeyPress) -> KeyPress.Result {
print("handleKeyPress", keyPress.key.character.unicodeScalars)
if (keyPress.key.character == "*") {
insertAtCursor(text: "×")
moveCursor(offset: 1)
return KeyPress.Result.handled
}
return KeyPress.Result.ignored
}
With hardware keyboard, log is:
onKeyPress 1
handleKeyPress 1
onKeyPress 2
handleKeyPress 2
input: changed from '' to '1'
input: changed from '1' to '12'
onKeyPress *
handleKeyPress *
Moving cursor from 2[any]
Moved to 4[utf8]
input: changed from '12' to '12×'
onKeyPress 3
handleKeyPress 3
input: changed from '12×' to '12×3'
onKeyPress 4
handleKeyPress 4
input: changed from '12×3' to '12×34'
with simulator virtual keyboard, log is:
input: changed from '' to '1'
input: changed from '1' to '12'
input: changed from '12' to '12*'
input: changed from '12*' to '12*3'
input: changed from '12*3' to '12*34'
Which shows onKeyPress is not called either.
Surprising. But confirmed here: https://stackoverflow.com/questions/79198074/onkeypress-doesnt-work-on-textfield-foreach-array
Topic:
UI Frameworks
SubTopic:
SwiftUI