如何在 swiftui 中访问其他视图结构中的视图结构

How to access a View Struct in other View struct in swiftui

在一种情况下,我有这个功能来注册和获取用户名

func signUp() {
 
    if self.email != "" {
        if self.password == self.repass {
    session.signUp(email: email, password: password) { (result, error) in
        
        if error != nil {
            self.error = error!.localizedDescription
            //self.error = "A senha deve ter 6 caracteres ou mais"
        }
            else{
                self.email = ""
                self.password = ""
                
                let db = Firestore.firestore()
                db.collection("Users").document(result!.user.uid).setData(["userName": userName]) { (error) in
                    if error != nil{
                    
                    }
                }
                
            }
        }
    }
        else{
            self.error = "Senhas não coincidem"
        }
}
    else{
        self.error = "Complete todos espaços"
}
}

在其他视图中,我想获取用户键入广告的用户名,但为此我需要 link 两个视图才能访问 func SignUp。怎么做?

编辑:

根据我得到的答案,我做了相应的修改:

会话存储:

@Published var session: User? = nil
var handle: AuthStateDidChangeListenerHandle?
@Published var userName: String = ""




func listen() {
    
    handle = Auth.auth().addStateDidChangeListener({ [self] (auth, user) in
        if let user = user {
            self.session = User(uid: user.uid, email: user.email!, userName: userName)
        }
        else {
            self.session = nil
        }
    })
}




struct User {

var uid:String
var email:String
var userName: String

}

主页视图----> var userName: User

Text(userName.userName)

应用程序启动,我可以使用用户名注册(并将其以 uid 作为文档存储在 Firestore 中),但未显示用户名。我想问题一定出在User(uid: "", email: "", password: "")。我不知道在那里添加什么。

顺便说一下,我正在考虑维护代码,然后使用文档 ID(已经是用户 uid)获取用户名,以便我可以访问它。还没有最终答案,但我正在努力。

编辑2: 我添加了@StateObject var session = SessionStore()

尝试使用:

@State var userName = User(uid: SessionStore().session?.uid ?? "", email: SessionStore().session?.email ?? "", userName: SessionStore().session?.userName ?? "")

还是不行

您的问题过于开放,但我会提供一个答案,希望能为您指明正确的方向。

首先,在 SwiftUI 中,将视图的概念(即屏幕上的内容排列方式)与驱动视图的数据概念分开。我的意思是,如果您需要一些数据,例如 userName,获取它的代码不应该知道或关心哪个视图将使用它。而Views,不应该关心数据是如何获取的。

其次,在 SwiftUI 中,不应将视图视为具有自己生命周期的“实体”(如在 UIKit 中)。它们只是定义 UI 排列方式的声明性语句。

例如,假设您有这个(假的)class 让用户登录,并且在登录时填充 userName 属性。这个class的实例是一个视图模型。

struct User {
   let userName: String
}

class Session: ObservableObject {
   @Published var user: User? = nil

   func signIn(_ completion: (User) -> ()) {
      DispatchQueue.main.asyncAfter(.now() + 0.5) {
         self.user = User(userName: "Mateus") // fake sign-in
         completion(self.user) // not really used in this example
      }
   }
}

@PublishedObservableObject 的组合是 SwiftUI 视图如何知道对该对象的更改做出反应的。如果您不知道它们的作用,请阅读更多关于它们的信息。

接下来,设计一个根视图,根据用户是否登录决定显示哪个内部视图:

struct RootView: View {
   @StateObject var session = Session()

   var body: some View {
      VStack() {
         if let user = session.user { 
            ContentView(user: user)  // view is conditionally rendered
         } else {
            Button("sign in") { self.signIn() }
         }
      }
   }

   func signIn() {
      self.session.signIn() {
         print("signed in...!")
      }
   }
}

@StateObject 管理视图的视图模型的生命周期。

正如您在上面看到的,ContentView 只会在 session.user 不是 nil 时呈现(即当用户已登录时),因此视图是由数据变化驱动的.我不需要提前在任何地方创建 ContentView 实例。

那么ContentView就直白了:

struct ContentView: View {
   var user: User

   var body: some View {
      Text("signed-in username: \(user.userName)")
   }
}