简体   繁体   English

如何为 SwiftUI 动态构建视图并呈现它?

[英]How can I dynamically build a View for SwiftUI and present it?

I've included stubbed code samples.我已经包含了存根代码示例。 I'm not sure how to get this presentation to work.我不确定如何让这个演示文稿发挥作用。 My expectation is that when the sheet presentation closure is evaluated, aDependency should be non-nil.我的期望是,在评估工作表演示闭包时, aDependency应该是非零的。 However, what is happening is that aDependency is being treated as nil, and TheNextView never gets put on screen.但是,正在发生的事情是aDependency被视为 nil,并且TheNextView永远不会出现在屏幕上。

How can I model this such that TheNextView is shown?我怎样才能 model 这样显示TheNextView What am I missing here?我在这里想念什么?

struct ADependency {}

struct AModel {
    func buildDependencyForNextExperience() -> ADependency? {
        return ADependency()
    }
}

struct ATestView_PresentationOccursButNextViewNotShown: View {
    @State private var aDependency: ADependency?
    @State private var isPresenting = false
    @State private var wantsPresent = false {
        didSet {
            aDependency = model.buildDependencyForNextExperience()
            isPresenting = true
        }
    }
    private let model = AModel()
    
    var body: some View {
        Text("Tap to present")
            .onTapGesture {
                wantsPresent = true
            }
            .sheet(isPresented: $isPresenting, content: {
                if let dependency = aDependency {
                    // Never executed
                    TheNextView(aDependency: dependency)
                }
            })
    }
}

struct TheNextView: View {
    let aDependency: ADependency
    
    init(aDependency: ADependency) {
        self.aDependency = aDependency
    }
    
    var body: some View {
        Text("Next Screen")
    }
}

This is a common problem in iOS 14. The sheet(isPresented:) gets evaluated on first render and then does not correctly update.这是 iOS 14 中的常见问题。 sheet(isPresented:)在第一次渲染时被评估,然后没有正确更新。

To get around this, you can use sheet(item:) .为了解决这个问题,您可以使用sheet(item:) The only catch is your item has to conform to Identifiable .唯一的问题是您的项目必须符合Identifiable

The following version of your code works:您的代码的以下版本有效:

struct ADependency : Identifiable {
    var id = UUID()
}

struct AModel {
    func buildDependencyForNextExperience() -> ADependency? {
        return ADependency()
    }
}

struct ContentView: View {
    @State private var aDependency: ADependency?
    private let model = AModel()
    
    var body: some View {
        Text("Tap to present")
            .onTapGesture {
                aDependency = model.buildDependencyForNextExperience()
            }
            .sheet(item: $aDependency, content: { (item) in
                TheNextView(aDependency: item)
            })
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM