为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
相关产品推荐
相关产品推荐

