In my iOS app, I’ve a VStack that consists of a view with a Checklist
and a view with a TextInput
:
var physique: some View {
NavigationView {
ScrollViewReader { scrollProxy in
VStack() {
NoteListView(notes: notes)
.onTapGesture { hideKeyboard() }
NoteInputView(scrollProxy: scrollProxy)
}
}
.navigationBarTitle(Textual content("Notes"))
}
}
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
On my NoteListView
, I’ve hooked up a .swipeAction to delete Notes:
Checklist(notes) { observe in
NotePreview(observe: observe)
.swipeActions(edge: .main, allowsFullSwipe: true) {
Button(position: .damaging) {
delete(observe)
} label: {
Label("Delete", systemImage: "trash")
}
.tint(.purple)
}
}
Whereas this hides the keyboard efficiently, it additionally prevents the faucet gesture to be acknowledged by the delete button on the swipe motion. Utilizing .simultaneousGesture
doesn’t repair this difficulty, the one approach to get the delete button to work when tapping is to take away any faucet gestures hooked up to mum or dad views—including .highPriorityGesture
to the button doesn’t fireplace, both. This looks as if a SwiftUI bug to me.
Tried Workaround—works unpredictably?
As a substitute of utilizing a VStack, I made a decision to maneuver to a ZStack that fills the whole display every time the keyboard is displaying. When the keyboard is displaying, a Spacer captures faucet occasions. When the keyboard shouldn’t be displaying, not faucets needs to be captured:
var physique: some View {
NavigationView {
ScrollViewReader { scrollProxy in
ZStack() {
NoteListView(notes: notes)
NoteInputView(scrollProxy: scrollProxy)
}
}
.navigationBarTitle(Textual content("Notes"))
}
}
In my NoteInputView
I now have @FocusState
to trace whether or not the TextInput has focus:
struct NoteInputView: View {
...
@FocusState var focusInputField: Bool
var physique: some View {
ZStack(alignment: .backside) {
if(focusInputField) {
Spacer()
.body(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(Rectangle())
.simultaneousGesture(TapGesture().onEnded({ _ in
focusInputField = false
print("I am nonetheless standing yeah yeah yeah")
print(focusInputField)
})).onTap
} else {
Spacer()
.body(maxWidth: .infinity, maxHeight: .infinity)
}
HStack() {
if(focusInputField) {
Button("", systemImage: "keyboard.chevron.compact.down") {
focusInputField = false
}
}
TextField("Enter a fast observe...", textual content: $newNoteContent, axis: .vertical)
.lineLimit(1...5)
}
}
}
}
Nevertheless, this works unreliably—generally, the Spacer
capturing the faucet will nonetheless print I am nonetheless standing yeah yeah yeah
regardless of focusInputField
being false. To this point, I’ve not been in a position to reliably reproduce when the Spacer stays or when it disappears.
Could be glad to listen to different workarounds, or suggestions on why this is perhaps working unreliably.