SwiftUI中dismiss环境变量替代方案求助:解决视图重渲染问题
SwiftUI 模态视图关闭的替代方案
当使用@Environment(\.dismiss)遇到_dismiss频繁变更导致视图重复计算、.task触发异常的iOS已知bug时,可以用以下几种替代方法关闭模态视图:
1. 绑定变量控制模态显隐
这是最直观的方案,通过父视图的绑定布尔值直接控制模态的展示与关闭,完全避开系统dismiss环境变量的问题。
// 父视图 struct ParentView: View { @State private var isModalPresented = false var body: some View { Button("打开模态") { isModalPresented = true } .sheet(isPresented: $isModalPresented) { ModalChildView(isPresented: $isModalPresented) } } } // 模态子视图 struct ModalChildView: View { @Binding var isPresented: Bool var body: some View { Button("关闭模态") { isPresented = false } } }
2. 自定义环境键传递关闭动作
如果不想直接传递绑定变量,可以自定义环境键,将关闭动作注入到环境中,用法和系统dismiss类似,但不会触发bug。
// 自定义环境键 private struct CustomDismissKey: EnvironmentKey { static let defaultValue: () -> Void = {} } extension EnvironmentValues { var customDismiss: () -> Void { get { self[CustomDismissKey.self] } set { self[CustomDismissKey.self] = newValue } } } // 父视图 struct ParentView: View { @State private var isModalPresented = false var body: some View { Button("打开模态") { isModalPresented = true } .sheet(isPresented: $isModalPresented) { ModalChildView() .environment(\.customDismiss) { isModalPresented = false } } } } // 模态子视图 struct ModalChildView: View { @Environment(\.customDismiss) private var customDismiss var body: some View { Button("关闭模态") { customDismiss() } } }
3. ObservableObject 管理模态状态
针对复杂页面场景,可以用ObservableObject集中管理模态状态,子视图通过观察该对象执行关闭操作。
class ModalManager: ObservableObject { @Published var isModalPresented = false func dismissModal() { isModalPresented = false } } // 父视图 struct ParentView: View { @StateObject private var modalManager = ModalManager() var body: some View { Button("打开模态") { modalManager.isModalPresented = true } .sheet(isPresented: $modalManager.isModalPresented) { ModalChildView(manager: modalManager) } } } // 模态子视图 struct ModalChildView: View { @ObservedObject var manager: ModalManager var body: some View { Button("关闭模态") { manager.dismissModal() } } }
内容的提问来源于stack exchange,提问作者Deepak Sharma
相关产品推荐
相关产品推荐

