有没有一种方法可以在 "tableView" 函数中使用 "func startObservingDB()" 中的 "data," "values," 和 "rowNumber" 常量?

Is there a way that I can use my "data," "values," and "rowNumber" constants from my "func startObservingDB()" in my "tableView" functions?

我知道问题与范围有关;我只是不知道是否有一个简单的修复方法可以在不改变我的代码的情况下完成。但对任何事情都持开放态度

    import UIKit
    import Firebase
    import FirebaseAuth
    import FirebaseFirestore

    class AdminViewController: UIViewController, UITableViewDelegate, 
UITableViewDataSource {

    @IBOutlet var custodianRunReportsTableView: UITableView!
    
    var dbRef: DatabaseReference!
    
    var data = [String]()



    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        startObservingDB()
        
        custodianRunReportsTableView.delegate = self
        custodianRunReportsTableView.dataSource = self
        // Do any additional setup after loading the view.
    }

    // Gets users' names from Cloud Firestore Database
    func startObservingDB() {
        let db = Firestore.firestore()
        let namesDocumentRef = db.collection("Users").document("Names")
        
        namesDocumentRef.addSnapshotListener { DocumentSnapshot, error in
            guard let document = DocumentSnapshot else {
                print("Error fetching document: \(error!)")
                return
            }
            guard let data = document.data() else {
                print("Document data was empty.")
                return
            }
            let values = data.values
            let rowNumber = data.count
            
            print("Current data: \(data)")
            print("Current data has the values: \(values)")
            print("Current data totals \(data.count) items.")
            
        }
        
        

    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("You tapped me!")
    }
    
}

    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rowNumber
    }
        
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = custodianRunReportsTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        cell.textLabel?.text = values[indexPath.row]
        print("Names in cell: \(values)")
        print("\(data)")
        
        return cell
    }
    
}

更新代码:

这是在回答原始 post 后更新的。代码不再有未解决的识别错误;但是,table 视图不显示任何单元格文本并且是空的。

class AdminViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet var custodianRunReportsTableView: UITableView!

var valuesArray:[String] = []

var data:[String] = []

var namesDocumentRef:DocumentReference!







override func viewDidLoad() {
    super.viewDidLoad()

    startObservingDB()
    
    custodianRunReportsTableView.delegate = self
    custodianRunReportsTableView.dataSource = self
    
}

// Gets users' names from Cloud Firestore Database
func startObservingDB() {
    var namesDocumentRef:DocumentReference!
    let db = Firestore.firestore()
    namesDocumentRef = db.collection("Users").document("Names")
    namesDocumentRef.addSnapshotListener { DocumentSnapshot, error in
        if error != nil{
            return
        }
        else {
            guard let snapshot = DocumentSnapshot, snapshot.exists else {return}
            guard let data = snapshot.data() else { return }
            self.valuesArray = Array(data.values) as! Array<String>
        }
    }
}
        

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("You tapped me!")
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return valuesArray.count
}
    
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = custodianRunReportsTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    
    cell.textLabel?.text = valuesArray[indexPath.row]
    return cell
}

}

在您的 class AdminViewController 中,您可以使用 self 引用在方法之外定义的属性(在您的示例中,您有 dbRef 可以像 self.dbRef 在方法中)。

所以我建议您为数据、值和行号创建属性并在 startObservingDB 方法中更改它们,而不是声明它们。这样您就可以在 tableView 方法中引用它们。

变量 datavaluesrowCount 在闭包内,所以你不能只写 values[indexPath.row] 因为你不能 return 来自内部关闭。通常 completionHandlers 用于此目的,但在这种情况下,您应该将 values 放在数组中,然后在 tableview 中使用。让我告诉你怎么做。

在 viewController 的开头声明一个字符串数组。

var valuesArray:[String] = []

然后,在里面修改你的startObservingDB()函数

func startObservingDB() {
    var docRef:DocumentReference!
    let db = Firestore.firestore()
    docRef = db.collection("Users").document("Names")
    docRef.addSnapshotListener { (docSnapshot, error) in
       if error != nil {
            return
           }
           else {
                   guard let snapshot = docSnapshot, snapshot.exists else {return}
                   guard let data = snapshot.data() else { return }
                    self.valuesArray = Array(data.values) as! Array<String>
                    self.tableView.reloadData()
                }
            }
       }

viewDidLoad调用这个函数

startObservingDB()

然后在tableView方法

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return ValuesArray.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  
    let cell = custodianRunReportsTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
     cell.textLabel?.text = valuesArray[indexPath.row]
     return cell
}