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

查看:709
本文介绍了如何在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天全站免登陆