如何在 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)
解释我的代码是如何工作的:@main
视图是 MedAppApp: App
。从那里,代码转到 ContentView
。如果 session.session != nil
,TransitionView
,否则,SignView
。从 SignView
继续,我有 SignInView
和 SignUpView
视图,它们分别有 Button(action: signIn)
和 Button(action: 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 中),但未显示用户名。我想问题一定出在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
}
}
}
@Published
和 ObservableObject
的组合是 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)")
}
}
在一种情况下,我有这个功能来注册和获取用户名
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)
解释我的代码是如何工作的:
@main
视图是MedAppApp: App
。从那里,代码转到ContentView
。如果session.session != nil
,TransitionView
,否则,SignView
。从SignView
继续,我有SignInView
和SignUpView
视图,它们分别有Button(action: signIn)
和Button(action: 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 中),但未显示用户名。我想问题一定出在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
}
}
}
@Published
和 ObservableObject
的组合是 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)")
}
}