Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
View 如何在swiftui的其他视图结构中访问视图结构_View_Swiftui - Fatal编程技术网

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

View 如何在swiftui的其他视图结构中访问视图结构,view,swiftui,View,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

在一个视图中,我有这个函数来注册并获取用户名

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

在另一个视图中,我希望获得用户键入的用户名并显示它,但为此,我需要链接两个视图以访问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

}
HomeView-->
var用户名:用户

Text(userName.userName)
  • 解释我的代码是如何工作的:
    @main
    视图是
    medappp:App
    。从那里,代码转到
    ContentView
    。如果
    session.session!=无
    转换视图
    ,否则,
    符号视图
    。继续从
    SignView
    ,我有
    SignInView
    SignUpView
    视图,它们分别有
    按钮(操作:signIn)
    按钮(操作:Signup)
    。从
    TransitionView
    继续,我有:

     struct TransitionView: View {
     @StateObject var LocationModel = LocationViewModel()
     @State var userName = User(uid: "", email: "", userName: "")
    
     var body: some View {
         HomeView(LocationModel: LocationModel, userName: userName)
     }
    }
    
  • @State var userName=…
    userName:userName
    需要添加

应用程序启动后,我可以使用用户名注册(它以uid作为文档存储在Firestore中),但不会显示用户名。我想问题一定出在用户(uid:,电子邮件:,密码:)上。我不知道该在那里补充什么

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

EDIT2: 我添加了@StateObject var session=SessionStore()

尝试使用:

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

还是不行

你的问题太开放了,但我会给出一个答案,希望能让你找到正确的方向

首先,在SwiftUI中,将视图的概念(即屏幕上事物的排列方式)与驱动视图的数据概念分开。我的意思是,如果您需要一些数据,比如
用户名
,那么获取它的代码不应该知道或关心哪个视图将使用它。和视图,不应该关心数据是如何获得的

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

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

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
      }
   }
}
@Published
observateObject
的组合是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
仅在
会话时呈现。用户
不是
nil
(即,当用户登录时),因此视图由数据更改驱动。我不需要提前在任何地方创建
ContentView
实例

那么
ContentView
就很简单了:

struct ContentView: View {
   var user: User

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

“但为此,我需要链接两个视图”——这不是SwiftUI的工作方式。取而代之的是,当您获得用户名时,更新一些视图模型(一个可观察对象)。然后,设计视图以基于此值使用条件更新,例如,如果让userName=vm.userName{ContentView()}Hey@NewDeve,谢谢您的回复。我不太明白你在说什么,我对你有点陌生SwiftUI@NewDev我在这里问了另一个问题(我添加了更多代码以便于理解)。请尝试在那里回答,以便我可以删除此项。感谢您再次回答,我刚刚更新了我的question@MateusNevesdeoliveira,您的更新引入了超出原始范围的更多问题。请随时提出新问题。有了这个答案,我只是想给你一个大致的方向。没问题。只是一个简单的问题:在代码中使用ContentView(user:user),因为您有“@”StateObject var session=session()和“@”已发布的var user:user?=零,对吗?为什么HomeView(用户名:userName)在我的代码中不起作用,就像在TransitionView中一样,我有“@”StateObject var session=SessionStore()和“@”Published var userName:Strong=”“?我没有完全理解代码中的内容,很难说