如何在 SwiftUI 中再次初始化 View? [英] How can I initialize View Again in SwiftUI?

查看:15
本文介绍了如何在 SwiftUI 中再次初始化 View?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I’m using SwfitUI in my project and I have a NavigationView and List. I’m clicking cell after open the detail view and click navigation back button. I want to remove view (it’s struct, in SwiftUI) after click navigation back button. Because if I click the same cell or button again, it isn’t initialize new view, it’s shows old view. I want to do refresh this view. How do I do?

我的 FirstView 结构是:

My FirstView Struct is:

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 结构是:

My DetailView Struct is:

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 中的一个单元格转到详细信息.然后我用后退按钮回来.我再次单击单元格以转到详细信息,但未打开新视图.它显示了旧视图.

First of all, I go to the detail by clicking a cell in FirstView. Then I come back with the back button. I click on a cell again to go to the details, but a new view does not open. It shows the old view.

在我忘记之前,我的生成器类是:

Before I forget, My Builder Class is:

final class DetailViewBuilder {
    static func make(object: Something) -> DetailView {

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

        return view
    }
}

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

Note: If I will use Sheet Presented, It's working. It's creating new View. But I want to use NavigationLink. Thank you.

推荐答案

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

You just need to defer your destination creation in your builder, and the @ViewBuilder is a good instrument for this.

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

It can be used the following wrapper for to create real destination only in when body will be rendered (ie. explicitly in time of navigation clicked in your case)

使用 Xcode 11.4/iOS 13.4 测试

Tested with 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
    }
}

现在是你的建设者

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

这篇关于如何在 SwiftUI 中再次初始化 View?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆