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 connected a .swipeAction to delete Notes:
Checklist(notes) { notice in
NotePreview(notice: notice)
.swipeActions(edge: .main, allowsFullSwipe: true) {
Button(function: .harmful) {
delete(notice)
} label: {
Label("Delete", systemImage: "trash")
}
.tint(.crimson)
}
}
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 problem, the one solution to get the delete button to work when tapping is to take away any faucet gestures connected to father or mother views—including .highPriorityGesture
to the button doesn’t hearth, both. This looks as if a SwiftUI bug to me.
Tried Workaround—works unpredictably?
As an alternative of utilizing a VStack, I made a decision to maneuver to a ZStack that fills your entire display screen every time the keyboard is displaying. When the keyboard is displaying, a Spacer captures faucet occasions. When the keyboard is just not displaying, not faucets must 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 notice...", textual content: $newNoteContent, axis: .vertical)
.lineLimit(1...5)
}
}
}
}
Nevertheless, this works unreliably—typically, 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 could be working unreliably.