danielsaidi / GestureButton

GestureButton is a SwiftUI button that can handle many different gestures.
MIT License
43 stars 0 forks source link

Scroll State crash #2

Open pinefin opened 3 weeks ago

pinefin commented 3 weeks ago

Hey Daniel,

I'm having an issue ever since I implemented the scrollGestureState view modifier, thinking maybe you'd have a way to circumvent this crash. (By the way the functionality is amazing, besides the crash.)

It's hard to ever see the crash actually happen, it's maybe once every 10-15 or so minutes so it was hard for me to replicate this. It also might be my app because I have quite a few state variables changing at once.

Here is where I have the scrollState, it's not in a ContentView, but this is somewhat near.

struct ListStack<Content: View>: View {
    let content: () -> Content;

    @StateObject private var scrollState = GlobalData.shared.scrollState

    init(@ViewBuilder  _ content: @escaping () -> Content) {
        self.content = content;
    }

    var body: some View {
        ZStack {
            ScrollView {
                VStack(content: content)
                    .background(.clear)
                    .padding(.leading, -8)
            }.scrollGestureState(scrollState)
        }
        .background(LinearGradient(gradient: Gradient(colors: [.gradStart, .gradStop]), startPoint: .topLeading, endPoint: .bottomTrailing))
    }
}

This is where I store the scrollState, from what your code looks like, this could be unconventional and the cause for un-planned behavior. I'm not sure

class GlobalData : ObservableObject {
    var scrollState = GestureButtonScrollState()

    static var shared -> GlobalData {
        if (instance == nil) {
            instance = GlobalData()
        }
        return instance!
    }
}

This is my GestureButton call

GestureButton(
        isPressed: $pressed,
        scrollState: GlobalData.shared.scrollState,
        pressAction: { pressed = true }, //
        releaseInsideAction: { pressed = false },
        releaseOutsideAction: { pressed = false },
        endAction: { pressed = false },
        label: { press in
            Rectangle()
                .fill(press ? Color.green : Color.red)
                .contentShape(Rectangle())
        })

This error happens inside of the scrollGestureState view modifier. see screenshot attached

Screenshot 2024-11-05 at 3 14 45 PM

Thank you!

pinefin commented 3 weeks ago

By the way, it looks like the crash happens on @State variable change, this is in a whole different view. Just the way the stack trace shows it

danielsaidi commented 3 weeks ago

Hi @pinefin

Thank you for reporting this! I haven't seen any of these crashes myself, but the workaround is so new that I'm sure there are a few hidden monsters, or at least unexpected side-effects.

Can you tell which state change that is causing the crash? Perhaps you update it from a background thread?

pinefin commented 3 weeks ago

@danielsaidi

It's actually not while touching the GestureButton at all, only while it's visible

It could be a race condition because I've only seen it like 2 or 3 times in the past 5 or so days in my testing and haven't got it to reproduce with a debugger attached.

I'll keep testing and let you know what I find! Most of my results are from TestFlight, and I can't particularly see what registers/local variables are set to

danielsaidi commented 3 weeks ago

Sounds great, thank you!