1

在有人建议从 PlayerController 的 viewWillAppear 中提取 Firebase 数据之前,我已经知道如何做到这一点,如果我这样做了,我知道如何将数据传递给 ScoreController。在这种情况下,我需要直接从单元格内提取数据,并以某种方式将数据从那里传回。

我在 PlayerController 中有一个 tableView,它显示了每个玩家的 randomPower、name 和 score。在 tableView 的单元格中,我使用函数从 Firebase 中提取名称和分数getScoreDataFromFirebase()。该函数直接位于 tableView 的 PlayerCell 内部,一旦我从 Firebase 获取值,我就会立即初始化单元格的名称和得分点。

在我调用 tableView 的 cellForRowAtIndexPath 内部cell.getScoreDataFromFirebase(),一切正常,因为两个出口都显示正确的值。

从那时起,我有了一个 ScoreController。When a tableView cell is chosen the score is sent to the ScoreController.

问题是因为我直接从单元格本身中提取数据,所以我可以将分数(从 Firebase 中提取)传递给 ScoreController 的唯一方法是首先didSet在单元格内设置一个分数属性。

当我从 Firebase 2nd 提取分数数据时仍在单元格内,我用它初始化 score 属性

在 tableView 的 cellForAtIndexPath 中的第三个我使用 anif let将值从单元格的 score 属性传递给 tableData。

当我第一次尝试将该 tableData 的 indexPath 发送到 ScoreController 时,有时它为零,即使单元格的 score 属性肯定有一个值(我曾经断点检查)。如果我选择前几个可见的 tableView 单元格中的任何一个,它们的 score 属性将具有 nil 值。但是,如果我进一步向下滚动单元格并向后滚动,那么这些相同的单元格将不再具有 nil score 属性。

我发现该if let语句在 Firebase 代码被提取之前正在运行,因此对于现场的前几个单元格,分数属性为零。奇怪的是,一旦我开始滚动,一切正常。

如何将直接从单元格中提取的值传递给 tableView 的 didSelectRow?

播放器型号:

class PlayerModel{
   name:String?
   score:String?
   randomPower:String?
}

TableViewCell 子类:

class PlayerCell:UITableViewCell{
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var scoreLabel: UILabel!
    @IBOutlet weak var randomPowerLabel: UILabel!

    internal var score: String?{
        didSet{
            print("**********\(score ?? "*********")")
        }
    }

    override func prepareForReuse() {
         super.prepareForReuse()
         nameLabel.text = " "
         scoreLabel.text = " "
    }

    func getScoreDataFromFirebase(){

         let scoreRef = usersRef?.child("score")

         scoreRef?.observe( .value, with: {
              (snapshot) in

              for child in snapshot.children{

                  let user = child as! DataSnapshot

                      for player in user.children{

                           let eachPlayer = player as! DataSnapshot

                           if let dict = eachPlayer.value as? [String:Any]{

                                 let name = dict["name"] as? String ?? " "
                                 let score = dict["score"] as? String ?? " "

                                 self.nameLabel.text = name
                                 self.scoreLabel.text = score

                                 self.score = score
                           }
                      }
              }
         }
    }
}

表视图:

class PlayerController: UITableViewDataSource, UITableViewDelegate{

@IBOutlet weak fileprivate var tableView: UITableView!

var players = [PlayerModel]() // this array is populated with data from a previous vc. The number of players in the array are the same exact number of players that's pulled from the getScoreDataFromFirebase() function

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.reloadData()
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as! PlayerCell

     let cellData = players[indexPath.row]     

     cellData.randomPowerLabel.text = cellData.power

     cell.getScoreDataFromFirebase()

     if let score = cell.score{
        cellData.score = score
     }

     return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    guard let indexPath = tableView.indexPathForSelectedRow else { return }

    let scoreVC = storyboard?.instantiateViewController(withIdentifier: "ScoreController") as! ScoreController

    scoreVC.score = players[indexPath.row].score

}
4

1 回答 1

1

您可以使用委托来实现此目的:
创建协议

protocol UpdateValueDelegate: class {
    func changeValue(score: String, row: Int)
}  

UIViewController应该是这样的:

PlayController : UITableViewDataSource, UITableViewDelegate, UpdateValueDelegate  
{
       var scoreDict:[String:String] = [:]
        //
       //  

      func changeValue(score: String, row: Int)
      {
            self.scoreDict["\(row)"] = score
      }
}  

cellForRowAtIndexPathset cell.delegate = selfcell.row = indexPath.row

UITableViewCell应该是这样的:

class PlayerCell:UITableViewCell: UITableViewCell
{
    weak  var delegate: UpdateValueDelegate?
    var row: Int?
    //
    //
} 

最后通过调用委托函数 从getScoreDataFromFirebase传递分数:

func getScoreDataFromFirebase()
{
    //
    //
    delegate. changeValue(score: localScore, row: self.row)
}

现在,您在 viewController 中有了值,可以didSelectRow使用全局字典 ** scoreDict** 轻松将其传递给该值。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
    var score = self.scoreDict["\(indexPath.row)"]
   // Use score
}
于 2018-02-13T19:01:27.977 回答