【问题标题】:How to pass static values in SwiftUI from one View to another?如何将 SwiftUI 中的静态值从一个视图传递到另一个视图?
【发布时间】:2021-08-04 08:02:49
【问题描述】:

我是学习 SwiftUI 和 XCode 的新手,无法弄清楚如何将变量从视图传递到另一个视图。我阅读了@State 和@Binding 变量,但据我所知,这是针对变化的值。我有一个静态值,我根据用户打开应用的日期计算得出。

变量是当前月相,本地存储在我的主 ContentView 中。我想将此变量传递给通过单击 NavigationLink 访问的第二个视图。

ContentView.swift

import SwiftUI

struct ContentView: View {
    
    
    var body: some View {
        
        
        let currentMoonPhaseArray = calculateMoonPhase()
        let moonPhase = currentMoonPhaseArray[0]
        
        NavigationView{
            ScrollView(.vertical, showsIndicators:true) {
                VStack(spacing:3){
                    NavigationLink(destination: MoonPhaseView()){
                        Text("Moon Phase - " + moonPhase)
                    }
                }
            }
        .frame(maxWidth: .infinity)
        .navigationTitle("MySky")
        .navigationBarTitleDisplayMode(.inline)
        }
        
    }
}

MoonPhaseView.swift

import SwiftUI

struct MoonPhaseView: View {
    
    
    var body: some View {
        HStack{
            Text("MoonPhaseView!")
        }
    }
}

struct MoonPhaseView_Previews: PreviewProvider {
    static var previews: some View {
        MoonPhaseView()
    }
}

我的目标是将 ContentView.swift 中计算出的月相传递给 MoonPhaseView.swift。我相信绑定是我读过的正确方法,但所有绑定实现似乎都是为了经常更新视图。

感谢任何帮助或指点!

【问题讨论】:

    标签: ios swift xcode swiftui


    【解决方案1】:

    你还没有展示moonPhase的类型是什么,所以我只是以String为例。

    
    struct ContentView: View {
        
        func calculateMoonPhase() -> [String] {
            return ["Full","Waxing","Waning"]
        }
        
        var body: some View {
            let currentMoonPhaseArray = calculateMoonPhase()
            let moonPhase = currentMoonPhaseArray[0]
            
            NavigationView{
                ScrollView(.vertical, showsIndicators:true) {
                    VStack(spacing:3){
                        NavigationLink(destination: MoonPhaseView(phase: moonPhase)){
                            Text("Moon Phase - " + moonPhase)
                        }
                    }
                }
                .frame(maxWidth: .infinity)
                .navigationTitle("MySky")
                .navigationBarTitleDisplayMode(.inline)
            }
        }
    }
    
    struct MoonPhaseView: View {
        var phase : String
        
        var body: some View {
            HStack{
                Text("MoonPhaseView!")
                Text(phase)
            }
        }
    }
    
    struct MoonPhaseView_Previews: PreviewProvider {
        static var previews: some View {
            MoonPhaseView(phase: "Full")
        }
    }
    

    请注意,每次使用MoonPhaseView 时,您必须提供一个phase 参数,以便它有一个值来填充var phase : String。您可以提供一个默认值,但这似乎在这里没有多大用处。


    与您的问题没有直接关系,但我可能会建议在 body 中计算阶段可能会导致不良结果,尤其是在计算成本高昂或必须联系 API 或某物。您可能需要考虑在onAppear 中执行此操作,并将其保存在ContentView 中的@State 变量中,或者甚至使用ObservableObject 作为视图模型并将相位存储在那里。

    【讨论】:

      【解决方案2】:

      您可以使用“环境”将系统范围的设置传递给视图和子视图。

      例如:

      @main
      struct TestApp: App {
          let moonPhaseValue = "Waxing"   // <--- some value 
          var body: some Scene {
              WindowGroup {
                  ContentView().environment(\.moonPhase, moonPhaseValue) // <--- pass it around
              }
          }
      }
      
      
      struct ContentView: View {
          @Environment(\.moonPhase) var moonPhase   // <--- the value again
          var body: some View {
              NavigationView {
                  VStack {
                      NavigationLink(destination: MoonPhaseView()) {
                          Text("Moon Phase - " + moonPhase)
                      }
                  }
              }.navigationViewStyle(StackNavigationViewStyle())
          }
      }
      
      struct MoonPhaseView: View {
          @Environment(\.moonPhase) var moonPhase  // <--- the value again
          var body: some View {
              HStack{
                  Text("MoonPhaseView is \(moonPhase)")
              }
          }
      }
      
      // create your own EnvironmentKey
      struct MoonPhaseKey: EnvironmentKey {
          static let defaultValue: String = "Full"
      }
      // create your own EnvironmentValues
      extension EnvironmentValues {
          var moonPhase: String {
              get { return self[MoonPhaseKey] }
              set { self[MoonPhaseKey] = newValue }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2022-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多