Swift iOS - 如何将TableViewCell的SubClass中直接获取的值传递给TableView的didSelectRow?

时间:2018-02-13 18:41:57

标签: ios swift uitableview indexpath

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

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

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

从那时起我就有了ScoreController。选择tableView单元格后,分数将发送到ScoreController。

问题是因为我直接从单元格内部提取数据 我唯一可以将得分(从Firebase中提取)传递给ScoreController的方法是第1次设置{{1}在单元格内得分属性。

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

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

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

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

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

PlayerModel:

if let

TableViewCell SubClass:

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

的TableView:

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
                           }
                      }
              }
         }
    }
}

1 个答案:

答案 0 :(得分: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
      }
}  

cellForRowAtIndexPath设置 cell.delegate = self cell.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中使用全局字典** scoreDict **轻松地将其传递给didSelectRow

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
    var score = self.scoreDict["\(indexPath.row)"]
   // Use score
}