swift - Simultaneous Gestures not Working on iOS 17 - Stack Overflow

admin2025-01-08  10

I am currently working on a settings menu and was hoping to use SwiftUI for it. It has all been working swimmingly until recently I tested it on an older iOS version, 17.5 and 17.7 and then the simultaneous gesture recognition stopped working and it could not scroll by moving on the rows. Here is the code that is producing the effects:

struct SettingsList: View {

    var body: some View {
        ScrollView(.vertical) {
            VStack(spacing: 17.5) {
                SettingsSection(content: [
                    SettingsRow(title: "A"),
                    SettingsRow(title: "B"),
                    SettingsRow(title: "C"),
                    SettingsRow(title: "D")
                ])
                .padding(.top, 10)
                SettingsSection(content: [
                    SettingsRow(title: "E", showsChevron: false)
                ])
                SettingsSection(content: [
                    SettingsRow(title: "F"),
                    SettingsRow(title: "G"),
                    SettingsRow(title: "H"),
                    SettingsRow(title: "I")
                ])
                SettingsSection(content: [
                    SettingsRow(title: "J")
                ])
                SettingsSection(content: [
                    SettingsRow(title: "K"),
                    SettingsRow(title: "L"),
                    SettingsRow(title: "M"),
                    SettingsRow(title: "N"),
                    SettingsRow(title: "O")
                ])
                SettingsSection(content: [
                    SettingsRow(title: "P"),
                    SettingsRow(title: "Q")
                ])
                .padding(.top, 25)
            }
            .padding(.vertical, 10)
        }
        
    }
}

struct SettingsSection: View {
    let content: [SettingsRow]
    
    init(content: [SettingsRow]) {
        self.content = content
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            ZStack {
                VStack(spacing: 0) {
                    ForEach(Array(content.indices), id: \.self) { index in
                        content[index]
                    }
                }
                VStack(spacing: SettingsRow.height) {
                    ForEach(0...content.count, id: \.self) { index in
                        if index > 0 && index != content.count {
                            Divider()
                                .padding(.leading, 15)
                                .frame(height: 0)
                        } else {
                            Divider()
                                .frame(height: 0)
                        }
                    }
                }
            }
            .background(Color.white)
        }
    }
}

struct SettingsRow: View {
    
    static let height: CGFloat = 53
    
    var title: String
    var showsChevron = true
    var onClick: () -> Void
    
    @GestureState private var isPressed = false
    @State private var isCancelled = false
        
    private let selectionColor = Color(red: 210.0 / 255.0, green: 209.0 / 255.0, blue: 214.0 / 255.0)
    private let chevronColor = Color(red: 197.0 / 255.0, green: 197.0 / 255.0, blue: 199.0 / 255.0)

    init(title: String, showsChevron: Bool = true, onClick: @escaping () -> Void = {}) {
        self.title = title
        self.showsChevron = showsChevron
        self.onClick = onClick
    }
    
    var backgroundColor: Color {
        return isPressed && !isCancelled ? Color.black.opacity(0.15) : Color.clear
    }
    
    var body: some View {
        HStack(spacing: 0) {
            Text(title)
                .font(.custom("Avenir-Light", size: 17))
                .foregroundColor(.black)
                .padding(.trailing, 10)
            Spacer()
            
            if showsChevron {
                Image(systemName: "chevron.right")
                    .font(.system(size: 13).weight(.semibold))
                    .foregroundColor(chevronColor)
            }
        }
        .padding(.horizontal, 15)
        .padding(.vertical, 12.5)
        .frame(height: Self.height)
        .contentShape(Rectangle()) // Makes the entire row tappable
        .background(backgroundColor) // Darkens when pressed
        .background(Color.white)
        .animation(.easeInOut(duration: 0.1), value: isPressed)
        .simultaneousGesture(
            DragGesture(minimumDistance: 0)
                .updating($isPressed) { value, isPressed, _ in
                    // Check vertical movement threshold
                    if abs(value.translation.height) > 10 { // Vertical threshold
                        isCancelled = true
                    } else {
                        isCancelled = false
                        isPressed = true
                    }
                }
                .onEnded { value in
                    if !isCancelled && abs(value.translation.height) <= 10 {
                        onClick()
                    }
                    isCancelled = false
                }
        )
    }
}

I wanted to make my code like this to be able to easily add sections and rows and felt SwiftUI was the best way to do so. If it is possible I would like to use it and if that means making a fallback implementation for iOS 17, that's okay.

In iOS 17 currently it only scrolls when tapping between the sections. I have tried numerous solutions including trying to make my own scroll view implementation and high priority gestures, all to no avail. How do I fix this for iOS 17?

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736271010a1484.html

最新回复(0)