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
}