Swift iOS -Как я могу передать значение, полученное непосредственно из подкласса TableViewCell в табличное представление didSelectRow?

Прежде чем кто-либо предложит извлечь данные Firebase из viewWillAppear PlayerController, я уже знаю, как это сделать, и если я сделал это таким образом, я знаю, как передать данные в ScoreController. В этой ситуации мне нужно извлечь данные непосредственно из ячейки и каким-то образом передать данные оттуда.

У меня есть TableView внутри PlayerController, который отображает randomPower, имя и счет каждого игрока. Внутри ячейки tableView я извлекаю имя и оценку из Firebase, используя функцию getScoreDataFromFirebase(), Функция находится непосредственно внутри PlayerCell tableView, и как только я получаю значения из Firebase, я тут же инициализирую имя ячейки и точки оценки.

Внутри tableView's cellForRowAtIndexPath я вызываю cell.getScoreDataFromFirebase() и все работает нормально, потому что оба выхода отображают правильные значения.

С этого момента у меня есть ScoreController. Когда ячейка tableView выбрана, оценка отправляется в ScoreController.

Проблема в том, что я извлекаю данные непосредственно из самой ячейки, и единственный способ передать счет (извлеченный из Firebase) в ScoreController - это установить 1-е значение didSet оценка свойства внутри клетки.

Все еще внутри ячейки, когда я извлекаю данные оценки из Firebase 2nd, я инициализирую свойство оценки с ним

3-й внутри cellForAtIndexPath tableView я использую if let передать значение из свойства счета ячейки в tableData.

Когда я впервые пытаюсь отправить indexPath этого tableData в ScoreController, иногда он равен нулю, хотя свойство Score ячейки определенно имеет значение (я использовал для проверки точек останова). Если я выберу одну из первых нескольких видимых ячеек таблицы, у них будет нулевое значение для свойства Score. Однако, если я прокручиваю дальше вниз по ячейкам и возвращаюсь назад, те же ячейки больше не будут иметь свойство нулевого счета.

То, что я узнал, было if let Оператор выполнялся до того, как код Firebase был извлечен, поэтому свойство Score было нулевым для первых нескольких ячеек, находящихся на сцене. Странно то, что все работает нормально, когда я начинаю прокручивать.

Как я могу передать значение, извлеченное непосредственно из ячейки, в didSelectRow tableView?

PlayerModel:

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

TableViewCell SubClass:

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

TableView:

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

}

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 set 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, откуда оно может быть легко передано didSelectRow используя глобальный словарь ** ScoreDict**.

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
    var score = self.scoreDict["\(indexPath.row)"]
   // Use score
}
Другие вопросы по тегам