SwiftUI技术问询:如何在不拖动Sheet到顶部时滚动其内的List
解决Sheet内List滚动与Sheet拖动冲突的问题
要实现像Instagram评论区那样,直接滚动Sheet内的List而不会先触发Sheet拖动到顶部的行为,你可以通过以下两种方案解决手势冲突问题:
方案一:仅允许顶部区域拖动Sheet(推荐,贴近Instagram交互逻辑)
这种方式将Sheet的拖动权限限制在顶部的SomeView区域,List区域直接响应滚动,不会触发Sheet拖动:
- 隐藏默认的Sheet拖动指示器
- 给顶部的
SomeView添加自定义拖动手势,用来控制Sheet尺寸
修改后的代码如下:
struct CustomSheetView: View { @Binding var currentDetent: PresentationDetent var body: some View { VStack { // 仅顶部区域可拖动调整Sheet SomeView() .gesture( DragGesture() .onChanged { value in let translationY = value.translation.height // 根据拖动距离切换Sheet尺寸 if translationY > 50 { currentDetent = .fraction(0.8) } else if translationY < -50 { currentDetent = .large } } ) Spacer() List { ForEach(1...40, id: \.self) { index in Text("Item \(index)") } } Spacer() SomeOtherView() } } } struct ContentView: View { @State private var isSheetVisible = false @State private var currentDetent: PresentationDetent = .fraction(0.8) var body: some View { Button("Open Sheet") { isSheetVisible = true } .sheet(isPresented: $isSheetVisible) { CustomSheetView(currentDetent: $currentDetent) .presentationDetents([.fraction(0.8), .large], selection: $currentDetent) .presentationDragIndicator(.hidden) // 隐藏默认拖动指示器 } } }
方案二:让List滚动手势优先响应
通过给List添加高优先级手势,强制List的滚动手势优先于Sheet的拖动手势,在List区域滚动时直接触发List滚动:
修改CustomSheetView中的List部分:
List { ForEach(1...40, id: \.self) { index in Text("Item \(index)") } } .highPriorityGesture( DragGesture(minimumDistance: 0) .onChanged { _ in } // 空实现,仅用于抢占手势优先级 )
这种方式实现更简单,但会导致整个List区域无法拖动Sheet,适合不需要保留Sheet全局拖动功能的场景。
内容的提问来源于stack exchange,提问作者Dgotin
相关产品推荐
相关产品推荐

