ios – SwiftUI: SwipeActions not working when faucet gesture is used elsewhere, FocusState unreliable

Spread the love


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.

Leave a Reply

Your email address will not be published. Required fields are marked *