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

Posted

技术标签:

【中文标题】如何为 SwiftUI 动态构建视图并呈现它?【英文标题】:How can I dynamically build a View for SwiftUI and present it? 【发布时间】:2021-02-27 19:22:25 【问题描述】:

我已经包含了存根代码示例。我不确定如何让这个演示文稿发挥作用。我的期望是,在评估工作表演示关闭时,aDependency 应该是非零。然而,正在发生的事情是 aDependency 被视为 nil,而 TheNextView 永远不会出现在屏幕上。

如何建模以显示TheNextView?我在这里错过了什么?

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")
    

【问题讨论】:

你想初始化aDependency on state change?这是必要条件吗? @TusharSharma 正确!是的 为什么不在初始化程序中做呢?当您点击文本时,您只需将 isPresented 切换为 true,就会调用工作表。由于您在初始化时已经初始化了依赖项,所以它不会是 nil 吗?这不是你想要的吗? @TusharSharma 在编译时依赖不是计算机,而是在用户单击按钮后计算的 what about doing-: "TheNextView(aDependency:model.buildDependencyForNextExperience())"。模型是提供对象,为什么不直接在展示表时传递呢?你也可以去掉wantsPresent和adependency state属性. 【参考方案1】:

这是 ios 14 中的常见问题。sheet(isPresented:) 在第一次渲染时被评估,然后没有正确更新。

要解决此问题,您可以使用sheet(item:)。唯一的问题是您的商品必须符合Identifiable

以下版本的代码有效:

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)
            )
    

【讨论】:

以上是关于如何为 SwiftUI 动态构建视图并呈现它?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中动态推送视图或呈现视图?

如何为视图提供固定位置,使其不受 SwiftUI 中滚动的影响

在 SwiftUI 中,如何为条形图创建动态矩形?

如何为通过 SwiftUI 中的自定义结构传递的 @State 值设置动画

SwiftUI - 有没有办法在没有 NavigationView 的情况下构建动态列表视图?

SwiftUI 和 MVVM:当视图模型更改“数据源”(`@Publish items`)本身时,如何为“列表元素更改”设置动画