SwiftUI 绑定到父视图重新渲染子视图

Posted

技术标签:

【中文标题】SwiftUI 绑定到父视图重新渲染子视图【英文标题】:SwiftUI Binding to parent view re-renders child view 【发布时间】:2021-07-21 14:55:38 【问题描述】:

我有一个从父视图获得绑定的子视图,它控制应用的侧边栏菜单。当我单击按钮切换 showSidebar 并打开菜单时,我的 vm 被重新创建,因为视图被重新渲染?有没有办法在不影响视图模型的情况下做到这一点?

struct OnboardingView: View 
    @Environment (\.presentationMode) var presentationMode
    @ObservedObject private var vm: OnboardingViewModel
    @State private var filtering = false
    @Binding var showSidebar: Bool

init(showSidebar: Binding<Bool>) 
    self._showSidebar = showSidebar
    self.vm = OnboardingViewModel()

【问题讨论】:

【参考方案1】:

试试这个...

改变这个

@ObservedObject private var vm: OnboardingViewModel

@StateObject private var vm: OnboardingViewModel = OnboardingViewModel()

摆脱

init(showSidebar: Binding<Bool>) 
    self._showSidebar = showSidebar
    self.vm = OnboardingViewModel()

在没有@StateObject 的视图中创建观察对象是不安全的

https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app

【讨论】:

我希望避免使用 StateObjects 以保持与 ios 13+ 的向后兼容性,但我可能不得不试一试。如果 StateObject 最初依赖于父 View 的某个值怎么办? 我猜到那时它将根据父值刷新,所以在这种情况下 ObservableObject 将是首选? 我需要一个例子来进一步解释,但是关于这个主题有很多 SO 问题。您可以在@State var vm: ObservableObject = OnboardingViewModel() 中创建对象,然后传递给@ObservedObject var vm: OnboardingViewModelstruct 是不可变的,可以由 SwiftUI 自行决定重新创建。您必须提供保持对象完整性的事实来源。有很多方法可以做到这一点。单例(不太理想)、class 中的变量等

以上是关于SwiftUI 绑定到父视图重新渲染子视图的主要内容,如果未能解决你的问题,请参考以下文章

如何将 SwiftUI 视图动态添加到父视图?

SwiftUI:避免使用 MKMapView+UIViewRepresentable 在 TabView 中重新创建/重新渲染视图

SwiftUI 将数组的元素作为绑定传递给子视图

如何将数据从子视图传递到父视图到 SwiftUI 中的另一个子视图?

SwiftUI 布局(Layout)基础

检查后在 SwiftUI 中将可选绑定设置为 nil 时出现异常