SwiftUI如何在独立外部函数中访问@State修饰的变量
问题解决说明
错误根因
@State修饰的username、email、password属于SignUp视图结构体的内部属性,仅在结构体内部作用域可以被访问。你写的signupbuttonpressed()是全局独立函数,不在SignUp的作用域范围内,所以无法读取这三个属性值,触发Cannot find 'xxx' in scope报错。
修复方案
只需要调整函数的归属位置,再修正原有代码的语法冗余、逻辑问题即可,具体修改如下:
- 将
signupbuttonpressed和createUser两个函数移入SignUp结构体内部,成为视图的私有方法 - 将注册按钮的点击事件绑定到内部的
signupbuttonpressed方法 - 清理代码中多余的闭合大括号,将密码输入框替换为
SecureField避免明文显示 - 修正Firebase数据库存储路径,调整为更合理的
users父节点下存储对应用户uid的数据
修正后完整代码
import SwiftUI import FirebaseAuth import FirebaseDatabase struct SignUp: View { @State var username: String = "" @State var email: String = "" @State var password: String = "" var body: some View { ZStack { LinearGradient(gradient: Gradient(colors: [Color.blue, Color.white]), startPoint: .topLeading, endPoint: .bottomTrailing) .ignoresSafeArea() Rectangle() .fill(Color.white) .frame(width: 300, height: 550) .cornerRadius(10) VStack(spacing: 30){ Image(systemName: "bitcoinsign.circle") .font(.system(size: 70, weight: .medium)) .padding() TextField("Username", text: $username) .frame(width: 200, height: 30) .padding() .overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.blue, style: StrokeStyle(lineWidth: 2.0))) .foregroundColor(.green) TextField("Email", text: $email) .frame(width: 200, height: 30) .padding() .overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.blue, style: StrokeStyle(lineWidth: 2.0))) .foregroundColor(.green) // 密码改用SecureField避免明文显示 SecureField("Password", text: $password) .frame(width: 200, height: 30) .padding() .overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.blue, style: StrokeStyle(lineWidth: 2.0))) .foregroundColor(.green) Button(action: signupbuttonpressed) { Text("Sign Up") .frame(width: 200, height: 20, alignment: .center) .padding() .background(Color.blue) .foregroundColor(Color.white) .cornerRadius(15) } } } } // 移动到结构体内部的方法,可以直接访问@State属性 private func signupbuttonpressed(){ createUser(withEmail: email, password: password, username: username) } private func createUser(withEmail email: String, password: String, username: String){ Auth.auth().createUser(withEmail: email, password: password) { (result, error) in if let error = error { print("Failed to sign user up", error.localizedDescription) return } guard let uid = result?.user.uid else { return } let values = ["email": email, "username":username] // 修正数据库存储路径 Database.database().reference().child("users").child(uid).updateChildValues(values) { (error, ref) in if let error = error { print("failed to update database values with error", error.localizedDescription) return } print("user successfully created..") } } } } struct SignUp_Previews: PreviewProvider { static var previews: some View { SignUp() } }
内容的提问来源于stack exchange,提问作者The Voyager
相关产品推荐
相关产品推荐

