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

SwiftUI问题:打开sheet时退出重启应用,点击区域偏移

SwiftUI Sheet重启后点击区域偏移Bug解决方案

问题现象

打开.sheet状态下退出应用,重启后回到sheet视图,拖拽关闭sheet返回主视图后,所有可点击元素的点击区域会出现向下偏移,需要点击原位置下方几像素才能触发响应。若从主视图退出应用则不会触发该Bug,且Bug会在主视图退出重启后消失;使用.fullScreenCover替代.sheet无此问题。

最简复现代码

struct ContentView: View {
    @State private var isOpen = false
    var body: some View {
        Button(action: {
            isOpen.toggle()
        }, label: {
            Text("Open sheet")
                .foregroundColor(.white)
                .padding()
                .background(.blue)
        })
        .sheet(isPresented: $isOpen, content: {
            Text("Sheet content")
        })
    }
}

重现步骤

  1. 点击蓝色按钮“Open sheet”上边框正下方位置,弹出sheet
  2. sheet打开状态下退出应用(iOS模拟器按cmd+shift+H返回主屏幕)
  3. 重启应用,回到sheet视图
  4. 拖拽关闭sheet返回主视图,此时出现点击区域偏移Bug
  5. 再次点击原按钮位置无响应,需点击下方几像素处才有效

已尝试无效方案

  • 将Button嵌入外部View
  • 用Text替代Button,通过.onTapGesture切换isOpen状态

关键发现

通过sheet内按钮调用@Environment(\.dismiss)关闭sheet不会触发Bug,但用户拖拽关闭时Bug依然存在。

解决方案

方案1:通过id修饰符强制重建主视图

利用SwiftUI的id修饰符特性,当sheet关闭时触发主视图重建,重置布局缓存。修改代码如下:

struct ContentView: View {
    @State private var isOpen = false
    @State private var viewID = UUID()
    
    var body: some View {
        Button(action: {
            isOpen.toggle()
        }, label: {
            Text("Open sheet")
                .foregroundColor(.white)
                .padding()
                .background(.blue)
        })
        .id(viewID) // 绑定唯一ID,ID变化时重建视图
        .sheet(isPresented: $isOpen, onDismiss: {
            // sheet关闭时更新ID,触发主视图重建
            viewID = UUID()
        }, content: {
            SheetContent()
        })
    }
}

struct SheetContent: View {
    @Environment(\.dismiss) var dismiss
    var body: some View {
        Button(action: { dismiss() }, label: {
            Text("Dismiss sheet")
        })
    }
}

方案2:禁用拖拽关闭(可选)

如果业务允许,可以禁用sheet的拖拽关闭功能,强制用户通过按钮关闭,从根源避免Bug触发:

.sheet(isPresented: $isOpen, content: {
    SheetContent()
        .interactiveDismissDisabled() // 禁用拖拽关闭
})

原理说明

该Bug疑似SwiftUI在处理sheet拖拽关闭后的布局缓存同步问题:拖拽关闭时,系统未正确重置主视图的布局坐标系,导致点击区域偏移。通过强制重建主视图(方案1)可以清除异常的布局缓存;禁用拖拽关闭(方案2)则直接规避了触发Bug的操作路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:41:39