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

SwiftUI:DisclosureGroup内按钮弹出.sheet首次展示即消失问题求助

问题原因与解决方案

问题根源

错误提示的核心是DisclosureGroup的展开过渡动画与Sheet的弹出操作发生了并行冲突。当你点击DisclosureGroup内的按钮时,DisclosureGroup的展开状态变更会触发UIKit内部的布局过渡(属于一种presentation类型的操作),此时立刻触发Sheet弹出,系统会检测到「已有一个presentation流程在进行中」,直接中断Sheet的展示,导致Sheet一闪而过并抛出错误。

保留现有设计的解决方案

方案1:延迟Sheet弹出,等待展开动画完成

通过给Sheet的弹出操作加一个短暂延迟,等DisclosureGroup的展开动画结束后再执行:

struct CompositedTestDisclosureGroup: View
{
    @State private var disclosureGroupIsExpanded = false
    @State private var sheetIsPresented = false
        
    var body: some View
    {
        TestDisclosureGroup(disclosureGroupIsExpanded: self.$disclosureGroupIsExpanded)
        {
            // 延迟0.2秒,适配DisclosureGroup的默认动画时长
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                self.sheetIsPresented = true
            }
        }
        .sheet(isPresented: self.$sheetIsPresented)
        {
            Text("Test")
        }
    }
}

方案2:禁用DisclosureGroup的展开动画

如果不需要DisclosureGroup的展开动画,可以直接关闭它,避免并行操作冲突:

struct TestDisclosureGroup: View
{
    @Binding var disclosureGroupIsExpanded: Bool
    var presentSheet: () -> Void
    
    var body: some View
    {
        DisclosureGroup("Disclosure Group", isExpanded: self.$disclosureGroupIsExpanded)
        {
            Button("Push Me")
            {
                presentSheet()
            }
            .buttonStyle(.borderedProminent)
        }
        // 针对展开状态变更禁用动画
        .animation(nil, value: disclosureGroupIsExpanded)
    }
}

方案3:将Sheet绑定到更高层级视图(优化实现)

基于你已知的方案做优化,把Sheet的状态托管在HomeView中,通过绑定传递给子视图,从根源避免子视图内的状态变更与动画冲突:

struct HomeView: View
{
    @State private var sheetIsPresented = false
    var body: some View
    {
        List
        {
            CompositedTestDisclosureGroup(sheetIsPresented: $sheetIsPresented)
        }
        .sheet(isPresented: $sheetIsPresented) {
            Text("Test")
        }
    }
 }

struct CompositedTestDisclosureGroup: View
{
    @State private var disclosureGroupIsExpanded = false
    @Binding var sheetIsPresented: Bool
        
    var body: some View
    {
        TestDisclosureGroup(disclosureGroupIsExpanded: self.$disclosureGroupIsExpanded)
        {
            self.sheetIsPresented = true
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 06:14:59