You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI如何在独立外部函数中访问@State修饰的变量

问题解决说明

错误根因

@State修饰的username、email、password属于SignUp视图结构体的内部属性,仅在结构体内部作用域可以被访问。你写的signupbuttonpressed()是全局独立函数,不在SignUp的作用域范围内,所以无法读取这三个属性值,触发Cannot find 'xxx' in scope报错。

修复方案

只需要调整函数的归属位置,再修正原有代码的语法冗余、逻辑问题即可,具体修改如下:

  1. 将signupbuttonpressed和createUser两个函数移入SignUp结构体内部,成为视图的私有方法
  2. 将注册按钮的点击事件绑定到内部的signupbuttonpressed方法
  3. 清理代码中多余的闭合大括号,将密码输入框替换为SecureField避免明文显示
  4. 修正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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:09:03