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

为PresentationDetent添加onChange修饰符致应用崩溃求助

SwiftUI监听PresentationDetent变化崩溃的解决方案

这个崩溃问题本质是父视图的onChange监听和sheet的生命周期不同步导致的——当sheet被 dismiss 时,相关的PresentationDetent状态可能会触发异常更新,而父视图的监听此时仍在生效,进而引发崩溃。

以下是几个可行的解决办法:

1. 将onChange移到sheet内部

把监听逻辑放在sheet的内容视图上,让它和sheet的生命周期绑定,这样只有当sheet存在时才会监听状态变化,避免无效回调触发崩溃。修改后的代码如下:

import SwiftUI

struct ContentViewSheetDetents: View {
    @State private var sheetDetent = PresentationDetent.medium
    @State private var isPresented = true

    var body: some View {
        Text("Hello, world!")
            .sheet(isPresented: $isPresented) {
                Text("Oh, hi!")
                    .presentationDetents(
                        [.medium, .large],
                        selection: $sheetDetent
                    )
                    // 把onChange移到sheet内容视图上
                    .onChange(of: sheetDetent) {
                        print("Detent changed")
                    }
            }
    }
}

#Preview {
    ContentViewSheetDetents()
}

2. 使用自定义绑定控制状态更新

如果必须在父视图处理逻辑,可以通过自定义绑定过滤异常的状态变化,比如忽略sheet dismiss时的无效更新:

import SwiftUI

struct ContentViewSheetDetents: View {
    @State private var sheetDetent = PresentationDetent.medium
    @State private var isPresented = true

    var body: some View {
        Text("Hello, world!")
            .sheet(isPresented: $isPresented) {
                Text("Oh, hi!")
                    .presentationDetents(
                        [.medium, .large],
                        selection: Binding(
                            get: { sheetDetent },
                            set: { newValue in
                                // 仅在sheet显示时更新状态
                                if isPresented {
                                    sheetDetent = newValue
                                    print("Detent changed")
                                }
                            }
                        )
                    )
            }
    }
}

#Preview {
    ContentViewSheetDetents()
}

3. 检查并升级iOS/Xcode版本

这个问题在iOS 16的部分小版本中属于已知bug,如果你使用的是较早的系统或开发工具,升级到最新版本可能直接解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:35:26