Search code examples
swifttimertableviewinvalidation

swift timer invalidation inside tableView cell


I'm a beginner just start learning swift for a few months now. Please help me with a timer invalidation issue. Feel free to make me feel stupid :). I know it's a bit messy and I'm willing to take pointer on how to do it better next time.

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCustomerCell
    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    let object = appDelegate.Queuelist[indexPath.row]

    if let genderInital = object.gender?.characters.first {
        cell.genderlabel.text = " \(genderInital)"
    }
    object.timerStarted()


    cell.waitedTimeLabel.text = "\(object.counter)"

    cell.nameLabel.text = object.name
    cell.languageLabel.text = object.language
    cell.reasonLabel.text = object.reasonOfVisit
    return cell
}

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

    var customerName: String?


    if let indexPathForName = tableView.indexPathForSelectedRow {

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let selectedCustomer = appDelegate.Queuelist[indexPathForName.row]
        customerName = selectedCustomer.name
        }


    let alertController = UIAlertController(title: customerName, message: "message", preferredStyle: .alert)

    let cancelAction = UIAlertAction(title: "cancel", style: .cancel, handler: nil)

    let editAction = UIAlertAction(title: "edit", style: .default) {action -> Void in

        self.performSegue(withIdentifier: "addSegue", sender: alertController)
        }
    let takeCustomerAction = UIAlertAction(title: "take customer", style: .default) {
        action -> Void in
        if let indexpath = tableView.indexPathForSelectedRow {
            let appDelegate = UIApplication.shared.delegate as! AppDelegate

            let object = appDelegate.Queuelist[indexpath.row]
            object.timer?.invalidate()
            appDelegate.Queuelist.remove(at: indexpath.row)
            appDelegate.storedQueuelist()
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    }

    alertController.addAction(takeCustomerAction)
    alertController.addAction(editAction)
    alertController.addAction(cancelAction)
    self.present(alertController, animated: true, completion: nil)
}

Solution

  • If you are assigning timer for each cell. You just need to declare method startTimer() and endTimer() on CustomCustomerCell class.

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCustomerCell
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let object = appDelegate.Queuelist[indexPath.row]
    
        if let genderInital = object.gender?.characters.first {
            cell.genderlabel.text = " \(genderInital)"
        }
        cell.startTimer()
    
        cell.waitedTimeLabel.text = "\(object.counter)"
        cell.nameLabel.text = object.name
        cell.languageLabel.text = object.language
        cell.reasonLabel.text = object.reasonOfVisit
    
        return cell
      }
    
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    //Use below method if you want to end timer for all cells
            //endTimerForAllCells(tableView)
        var customerName: String?
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let selectedCustomer = appDelegate.Queuelist[indexPath.row]
        customerName = selectedCustomer.name
    
        let alertController = UIAlertController(title: customerName, message: "message", preferredStyle: .alert)
    
        let cancelAction = UIAlertAction(title: "cancel", style: .cancel, handler: nil)
    
        let editAction = UIAlertAction(title: "edit", style: .default) {action -> Void in
        self.performSegue(withIdentifier: "addSegue", sender: alertController)
        }
    
        let takeCustomerAction = UIAlertAction(title: "take customer", style: .default) {
        action -> Void in
    
        if let indexpath = tableView.indexPathForSelectedRow {
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
    
            if let cell = tableView.cellForRowAtIndexPath(indexPath) as? CustomCustomerCell{
            cell.endTimer()
            }
            appDelegate.Queuelist.remove(at: indexpath.row)
            appDelegate.storedQueuelist()
            tableView.deleteRows(at: [indexPath], with: .fade)
          }
       }
    
        alertController.addAction(takeCustomerAction)
        alertController.addAction(editAction)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)
      }
    
    //Below method is use to end timer of all cells
    func endTimerForAllCells(tableView:UITableView){
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
         let totalRows = appDelegate.Queuelist
         if totalRows.count != 0{
            for row in 0...totalRows.count - 1{
                let index = NSIndexPath(forRow: row, inSection: 0)
                if let cell = tableView.cellForRowAtIndexPath(index) as? CustomCustomerCell{
                    cell.endTimer()
                  }
                }
              }
            }
          }
    

    Declaring method for timer in CustomCustomerCell class.

    private var timer: Timer?
    func startTimer(){
    
        timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(methodToDoSomethingAtEachInterval), userInfo: nil, repeats: true)
    }
    
    func endTimer() {
        timer?.invalidate
        timer = nil
    }
    
    func methodToDoSomethingAtEachInterval(){
     //Do something at each time interval for each tableviewCell
    }