You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI修复长按缩放控件时ScrollView无法滚动的问题

解决长按控件时ScrollView无法滚动的问题

问题根源在于你添加的LongPressGesture默认会抢占触摸事件的处理优先级,导致ScrollView的滚动手势被拦截,只有触摸无手势绑定的空白区域时才能触发滚动。以下是两种可行的解决方案:

方案1:调整手势优先级(推荐)

使用lowPriorityGesture替代默认的gesture方法,让ScrollView的滚动手势拥有更高优先级。这样当你在控件上长按的同时开始滚动,ScrollView会优先响应滚动操作;只有当你保持静止达到3秒的长按最小时长时,才会触发缩放效果。

修改后的代码:

struct TestView: View {
    
    @GestureState var isDetectingLongPress = false
    
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            VStack(spacing: 25) {
                RoundedRectangle(cornerRadius: 12.5, style: .continuous)
                    .fill(Color.blue)
                    .frame(height: 200)
                    .padding(25)
                    .scaleEffect(!isDetectingLongPress ? 1.0 : 0.875)
                    .brightness(!isDetectingLongPress ? 0.0 : -0.125)
                    .animation(.easeInOut(duration: 0.125), value: isDetectingLongPress)
                    .lowPriorityGesture(
                        LongPressGesture(minimumDuration: 3)
                            .updating($isDetectingLongPress) { currentState, gestureState, transaction in
                                gestureState = currentState
                                transaction.animation = Animation.easeIn(duration: 2.0)
                            }
                            .onEnded { finished in
                                
                            }
                    )
            }
        }
    }
}

方案2:结合拖动手势精细控制

如果需要在用户开始拖动时立即取消长按状态,可以将LongPressGesture与DragGesture组合为SimultaneousGesture,当拖动距离超过设定阈值时,重置长按状态:

struct TestView: View {
    
    @GestureState var isDetectingLongPress = false
    
    var body: some View {
        ScrollView(.vertical, showsIndicators: false) {
            VStack(spacing: 25) {
                RoundedRectangle(cornerRadius: 12.5, style: .continuous)
                    .fill(Color.blue)
                    .frame(height: 200)
                    .padding(25)
                    .scaleEffect(!isDetectingLongPress ? 1.0 : 0.875)
                    .brightness(!isDetectingLongPress ? 0.0 : -0.125)
                    .animation(.easeInOut(duration: 0.125), value: isDetectingLongPress)
                    .gesture(
                        SimultaneousGesture(
                            LongPressGesture(minimumDuration: 3)
                                .updating($isDetectingLongPress) { currentState, gestureState, transaction in
                                    gestureState = currentState
                                    transaction.animation = Animation.easeIn(duration: 2.0)
                                }
                                .onEnded { finished in
                                    
                                },
                            DragGesture(minimumDistance: 5)
                                .onChanged { _ in
                                    isDetectingLongPress = false
                                }
                        )
                    )
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 11:30:55