memory-management - 如何在 SwiftUI 中再次初始化 View ?

标签 memory-management struct swiftui navigationlink

我在我的项目中使用 SwfitUI,我有一个 NavigationView 和 List。我在打开详细信息 View 并单击导航返回按钮后单击单元格。单击导航后退按钮后,我想删除 View (它是结构,在 SwiftUI 中)。因为如果我再次单击相同的单元格或按钮,它不会初始化新 View ,而是显示旧 View 。我想刷新这个 View 。我该怎么办?

我的 FirstView 结构是:

struct FirstView: View {

    @ObservedObject var viewModel: FirstViewModel

    var body: some View {
        List(self.viewModel.objects, id: \.id) { object in
            ZStack {
                DetailViewCell(object: object)
                NavigationLink(destination: DetailViewBuilder.make(object)) {
                    EmptyView()
                }.buttonStyle(PlainButtonStyle())
            }
        }
    }
}

我的 DetailView 结构是:
struct DetailView: View {

    @ObservedObject var viewModel: DetailViewModel

    var body: some View {
        ZStack(alignment: .top) {
            Color.mainBackground.edgesIgnoringSafeArea(.all)
            VStack {
                ZStack {
                    Image("Square")
                    Image(self.viewModel.currentImage)
                }
                Text(self.viewModel.currentText)
                    .padding()
                    .frame(alignment: .center)
                    .minimumScaleFactor(0.1)
                Spacer()
                Button(action: {
                    self.viewModel.pressedPlayOrPauseButton()
                }, label: {
                    Image(self.viewModel.isPlaying ? "Pause" : "Play").foregroundColor(Color("Orange"))
                }).padding()
            }
        }
    }
}

首先,我通过单击 FirstView 中的一个单元格转到详细信息。然后我用后退按钮回来。我再次单击单元格以转到详细信息,但未打开新 View 。它显示了旧 View 。

在我忘记之前,我的生成器类是:
final class DetailViewBuilder {
    static func make(object: Something) -> DetailView {

        let viewModel = DetailViewModel(object: object)
        let view = DetailView(viewModel: viewModel)

        return view
    }
}

注意:如果我将使用 Sheet Presented,它会起作用。它正在创建新的 View 。但我想使用 NavigationLink。谢谢你。

最佳答案

您只需要在构建器中延迟目标创建,然后 @ViewBuilder是一个很好的工具。

只有在 body 时才可以使用以下包装器来创建真正的目的地将被呈现(即在您的情况下明确点击导航时间)

使用 Xcode 11.4/iOS 13.4 测试

struct DeferView<Content: View>: View {
    let content: () -> Content

    init(@ViewBuilder _ content: @escaping () -> Content) {
        self.content = content
    }
    var body: some View {
        content()          // << everything is created here
    }
}

现在你的 builder
final class DetailViewBuilder {
    static func make(object: Something) -> some View {
        DeferView {
           DetailView(viewModel: DetailViewModel(object: object))
        }
    }
}

关于memory-management - 如何在 SwiftUI 中再次初始化 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61238773/

相关文章:

c++ - 为什么我的自定义堆栈类使用这么多内存?

matlab - Matlab 使用什么算法来动态调整向量和矩阵的大小?

c++ - VirtualQueryEx 与 ReadProcessMemory 的关系

C++ 对象的快速排序 vector

swift - 类型 '()' 不能符合 'View' ;只有 struct/enum/class 类型可以符合使用 swift ui 调用调用函数的协议(protocol)

memory-management - OpenCl 清理导致段错误

java - 如何从 Java 通过套接字 C++ 兼容结构发送?

C++ 结构 : reference to overloaded function could not be resolved

ios - 可快速滚动全屏 View

text - 如何在 SwiftUI 中制作文本笔划?