drebin96
drebin96

Reputation: 176

ReloadData from another class cell in TableView

I am trying to update tableview from the button pressed in another tableviewcell. Here is code of my VC with table view:


import UIKit

class ResultsVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    
    
    @IBOutlet weak var teamTable: UITableView!
    @IBOutlet weak var wordsTable: UITableView!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        wordsForTheRound.removeLast()
        print(results)
        
        teamTable.delegate = self
        teamTable.dataSource = self
        wordsTable.delegate = self
        wordsTable.dataSource = self
        
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == self.teamTable {return results.count}
        if tableView == self.wordsTable {return results[0].words.count}
        return 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if tableView == self.teamTable {
            if let cell = tableView.dequeueReusableCell(withIdentifier: "ResultsTeamsCell") as? ResultsTeamsCell {
                cell.updateCell(result: results[indexPath.row])
                return cell
            }
        }
        if tableView == self.wordsTable {
            if let cell = tableView.dequeueReusableCell(withIdentifier: "ResultsWordsCell") as? ResultsWordsCell {
                cell.updateCell(wordIncmoing: results[0].words[indexPath.row], tf: results[0].wordIsCorrect[indexPath.row])
                return cell
            }
        }
            return UITableViewCell()
    }
    
    
    @IBAction func reloadTables(_ sender: Any) {
        teamTable.reloadData()
        wordsTable.reloadData()
    }
    
    


}

and the code of my tableviewcell where I need the teamTable to reload whilte i tap on buttons TFBtnPressed

import UIKit

class ResultsWordsCell: UITableViewCell {

    @IBOutlet weak var word: UILabel!
    @IBOutlet weak var TFBtn: UIButton!
    
    func updateCell(wordIncmoing: String, tf: Bool) {
        word.text = wordIncmoing
        TFBtn.setTitle("\(tf)", for: .normal)
    }
    @IBAction func TFBtnPressed(_ sender: Any) {
        if TFBtn.title(for: .normal) == "false" {
            TFBtn.setTitle("true", for: .normal)
            changeWordStatus(word: word.text!)
            results[0].score += 1
           
            print(results)
        } else {
            TFBtn.setTitle("false", for: .normal)
            changeWordStatus(word: word.text!)
            results[0].score -= 1
           
            print(results)
        }
    }
    
    func changeWordStatus(word: String) {
        for i in 0...results[0].words.count - 1 {
            if word == results[0].words[i] {
                results[0].wordIsCorrect[i] = !results[0].wordIsCorrect[i]
            }
        }
    }
    
}

I read a lot of articles and it is probably that it should set up a tableview delegate, but I could not figure out how to do it.

Upvotes: 0

Views: 170

Answers (2)

You can create a protocol to have communication between your view controller and table view cell.

Create a new protocol inside of your "ResultsWordsCell";

import UIKit
            
protocol ResultsWordsCellDelegate {
    func didTapRefreshButton()
}
            
class ResultsWordsCell: UITableViewCell {
    .....
    var resultsWordsCellDelegate: ResultsWordsCellDelegate?
    .....
    @IBAction func TFBtnPressed(_ sender: Any) {
        .....
        resultsWordsCellDelegate?.didTapRefreshButton()
        .....
    }

On ResultsVC' s cellForRowAt func;

add -> cell.resultsWordsCellDelegate = self

Now, create a new extension on ResultsVC;

class ResultsVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
.....
.....
}

extension ResultsVC: ResultsWordsCellDelegate {
    func didTapRefreshButton {
        self.wordsTable.reloadData()
        self.teamTable.reloadData()
    }
}

Upvotes: 1

hessam
hessam

Reputation: 432

you can use clouser. first create typealise for callBack like this:

typealias CallBack = () -> Void

and define clouser inside tableViewCell:

@IBOutlet weak var word: UILabel!
@IBOutlet weak var TFBtn: UIButton!

public var callBack: CallBack?

and call variable inside TFBtnPressed:

@IBAction func TFBtnPressed(_ sender: Any) {
        if TFBtn.title(for: .normal) == "false" {
            TFBtn.setTitle("true", for: .normal)
            changeWordStatus(word: word.text!)
            results[0].score += 1
           
            print(results)
        } else {
            TFBtn.setTitle("false", for: .normal)
            changeWordStatus(word: word.text!)
            results[0].score -= 1
           
            print(results)
        }
        
        // set callBack
        callBack?()
    }

and inside dequeue Cell change this:

   cell.updateCell(wordIncmoing: results[0].words[indexPath.row], tf: results[0].wordIsCorrect[indexPath.row])
        
        cell.callBack = { [weak self] in
            guard let self = self else {
                return
            }
            
// reload table here
            self.wordsTable.reloadData()
            self.teamTable.reloadData()
            
        }

all code ResultWordsCell:

typealias CallBack = () -> Void

class ResultsWordsCell: UITableViewCell {
    
    @IBOutlet weak var word: UILabel!
    @IBOutlet weak var TFBtn: UIButton!
    public var callBack: CallBack?
    
    func updateCell(wordIncmoing: String, tf: Bool) {
        word.text = wordIncmoing
        TFBtn.setTitle("\(tf)", for: .normal)
    }
    @IBAction func TFBtnPressed(_ sender: Any) {
        if TFBtn.title(for: .normal) == "false" {
            TFBtn.setTitle("true", for: .normal)
            changeWordStatus(word: word.text!)
            results[0].score += 1
           
            print(results)
        } else {
            TFBtn.setTitle("false", for: .normal)
            changeWordStatus(word: word.text!)
            results[0].score -= 1
           
            print(results)
        }
        
        // set callBack
        callBack?()
    }
    
    
    
    func changeWordStatus(word: String) {
        for i in 0...results[0].words.count - 1 {
            if word == results[0].words[i] {
                results[0].wordIsCorrect[i] = !results[0].wordIsCorrect[i]
            }
        }
    }
    
}

Upvotes: 0

Related Questions