I want my app to emulate the interface of apple's reminder app:
The app should set the focus to a newly created item
- either by clicking an "add" button regardles of the editing status on the list
- or by hitting the "enter" button on the soft keyboard while editing a currently selected list item.
I'm using a simple list with a custom TextField named editableListItemView which uses a firstResponderUUID of the enclosing ContentView to set the focus to the currently selected or newly created field.
The add button is working like a charm: the keyboard stays in place solidly and the cursor switches from the currently edited field to the newly created one.
The onSubmit code does exibit two annoying alternative behaviors:
- When setting the firstResonderID to the newly created entries UUID only (isFocused not set) the keyboard slides down and up again.
- Setting the focus first back to the item currently submitted followed by setting the firstResponderID the keyboard stays in place but toggles briefly into CapsLock on and the back to Caps Lock off.
Here's the View with the list:
struct ContentView: View {
@Binding var items: [TodoItem]
@State var firstResponderUUID: UUID? = nil
var body: some View {
NavigationView {
VStack {
List {
ForEach($items) { $item in
editableListItemView(item: item, firstResponderID: $firstResponderUUID, items: $items)
}
}
Button("add without bounce") {
let newItem = TodoItem()
items.append(newItem)
firstResponderUUID = newItem.id
}
}
.navigationTitle("Todo list")
}
}
}
The firstResponderUUID is handed down to the editableListItemView for setting the
focus both on the list level as on the item level accordingly:
struct editableListItemView: View {
@FocusState private var isFocused : Bool
@StateObject var item : TodoItem
@Binding var firstResponderID: UUID?
@Binding var items: [TodoItem]
var body: some View {
TextField("Title", text: $item.title)
.focused($isFocused)
.task {
isFocused = (item.id == self.firstResponderID)
}
.submitLabel(.go)
.onSubmit {
// the following line keeps the keyboard stays in place but toggles Caps-lock on/off
isFocused = true // with the line commented the keyboard briefly slides down and up again
let item1 = TodoItem()
item1.title = "new Item from commit"
items.append(item1)
firstResponderID = item1.id
}
}
}
class TodoItem: Identifiable, ObservableObject {
let id = UUID()
var title: String = "untitled"
}
Any idea on how to get the keyboard stay in place and stable for the onSubmit part?
Any Lead/Help appreciated. Thx.
A bit more background
- Fully working code for my example app can be found at https://github.com/cfwdman/editableList
- In the larger/real app the TodoItems are based on Core Data objects which are available through the object context which is passed into the view hierarchy as an environment and fetchrequest. Hence no passing/injecting of the list into the item. This is just for simplifaction of the code-
- before isFocused became available (< iOS 15) I used the https://github.com/siteline/SwiftUI-Introspect package (with the same sliding effect) for making the TextField the firstResponder.