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

SwiftUI实现Sheet点击任意位置展开且不阻塞常规点击手势

解决SwiftUI Sheet点击展开不阻塞内部交互的问题

你当前给Sheet的整个内容容器加了onTapGesture,导致所有内部点击都被这个手势拦截,NavigationLink只能响应长按。要实现点击空白区域展开Sheet,同时不影响内部交互,直接修改ExampleSheet的结构即可:

struct ExampleSheet: View {
    let heights = stride(from: 0.1, through: 1.0, by: 0.25).map { PresentationDetent.fraction($0) }
    @State private var height = PresentationDetent.fraction(0.15)
   
    let players = [
        "Roy Kent",
        "Richard Montlaur",
        "Dani Rojas",
        "Jamie Tartt",
    ]
    
    var body: some View {
        ZStack { // 用ZStack替代原VStack,实现分层手势响应
            // 底层透明视图,占满Sheet区域,仅空白处点击触发展开
            Color.clear
                .onTapGesture {
                    height = .large
                }
            
            // 原内容放在上层,交互元素手势优先响应
            NavigationView {
                List(players, id: \.self) { player in
                    NavigationLink(destination: PlayerView(name: player)) {
                        Text(player)
                    }
                }
            }
            .presentationDetents([.fraction(0.15), .medium, .large], selection: $height)
            .interactiveDismissDisabled()
        }
    }
}

关键逻辑说明

  • 用ZStack将透明底层视图和原内容分层,底层视图的点击手势只会在空白区域触发(因为上层的交互元素会优先捕获点击事件)
  • 内部的NavigationLink等交互组件处于ZStack上层,它们的常规点击手势不会被底层手势拦截,能正常响应跳转
  • 如果你的项目基于iOS 16+,建议把NavigationView替换为NavigationStack,适配最新SwiftUI规范:
    NavigationStack {
        List(players, id: \.self) { player in
            NavigationLink(destination: PlayerView(name: player)) {
                Text(player)
            }
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:35:26