Search code examples
swiftuitableviewtimertableviewcountdowntimer

My timer label takes up a new number after scrolling


Screenshot

My timer label takes up a new number after scrolling or reloding tableview, and at the same time it shows a few numbers per second. Can anyone help i want my label show on ?

I want my label to show only the number that it first comes in

In the pictures that you see, after a scroll or a relay table, the timers display several values ​​per second every second. I put my codes and pictures

import Alamofire
import Foundation

class Games: UIViewController, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var gamesTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        Alamofire.request("http://188.158.121.200:3030/shans.com/get_main_room_list", method:.post, headers: headers).responseJSON { (newresponse) in
            do {
                let decoder = JSONDecoder()
                let response = try decoder.decode(Root1.self, from: newresponse.data!)
                switch(response.joinedUser) {
                case  .joinedUserElementArray( let arr):
                    AppDelegate.AllofGames_Ids = arr.map { $0.id }
                case .string( _) :
                    break
                }
                if AppDelegate.AllofGames.isEmpty == true {
                    for each in response.allRooms {
                        let epocTime = TimeInterval(Int(each.matchTime)!) / 1000
                        if each.finished == true || AppDelegate.AllofGames_Ids.contains(each.id)  {
                            //Do nothing
                        }else {
                            let structGames = StructAllofGames(finished: each.finished, pic: each.pic, _id: each.id, coininput: each.coinInput, Award_money: each.awardMoney, Award_coin: each.awardCoin, Match_time: Int(epocTime), Winner_number: each.winnerNumber, Free: each.capacity.free, Total: each.capacity.total)
                            AppDelegate.AllofGames.append(structGames)
                            DispatchQueue.main.async{
                                self.gamesTableView.reloadData()
                            }//dispatch
                        }//else
                    }
                } else {
                    print("fk")
                }
            }
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return AppDelegate.AllofGames.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
        let Cell =  tableView.dequeueReusableCell(withIdentifier: "tableview1", for: indexPath) as! MyCustomCell

        Cell.SekeVorudi.text = String(AppDelegate.AllofGames[indexPath.row].coininput)
        Cell.jaize.text =  String(AppDelegate.AllofGames[indexPath.row].Award_money) + "تومان"
        Cell.ZarfiatOtagh.text = String(AppDelegate.AllofGames[indexPath.row].Total) + "/" + String(AppDelegate.AllofGames[indexPath.row].Free)
        Cell.TedadBarande.text = String(AppDelegate.AllofGames[indexPath.row].Winner_number)
        let  Fulllink    = AppDelegate.AllofGames[indexPath.row].pic
        Cell.imageview.downloaded(from: Fulllink)
        let (h,m,s)  = secondsToHoursMinutesSeconds(seconds: AppDelegate.AllofGames[indexPath.row].Match_time)
        let HoursToMinute = h * 60
        let AllOfMinutes = HoursToMinute + m
        Cell.timer(m: AllOfMinutes, s: 0)
        return Cell
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

}

and my codes in tableview cell:

class MyCustomCell: UITableViewCell {
    @IBOutlet weak var timelabel: UILabel!
    @IBOutlet weak var SekeVorudi: UILabel!
    @IBOutlet weak var jaize: UILabel!
    @IBOutlet weak var TedadBarande: UILabel!
    @IBOutlet weak var ZarfiatOtagh: UILabel!
    @IBOutlet weak var imageview: UIImageView!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }

    func timer(m: Int, s: Int) {
        DispatchQueue.global(qos: .userInteractive).async {
            var hour : Int = m/60
            var minute : Int = m % 60
            var second : Int = s

            DispatchQueue.main.async {
                self.timelabel.text = (String(format: "%02d:%02d:%02d", hour, minute, second))
            }

            while true {
                sleep(1)
                if hour == 0 && minute == 0 && second == 0 {
                    DispatchQueue.main.async {
                        UIView.animate(withDuration: 1, animations: {
                            self.timelabel.alpha = 0
                        })
                    }
                } else if second == 0 {
                    if minute != 0 {
                        minute = minute - 1
                        second = 59
                    } else if second == 0 && minute == 0 {
                        hour = hour - 1
                        minute = 59
                        second = 59
                    }
                } else if second != 0 {
                    second = second - 1
                }
                DispatchQueue.main.async {
                    self.timelabel.text = (String(format: "%02d:%02d:%02d", hour, minute, second))
                }
            }
        }
    }
}  

Solution

  • Set an optional variable on the top of your UIViewController and set its value to your desired cell number, and in CellForRowAt check that value if it was nil, if not set your label to that number, if its nil just keep going normally as you usually do.

    This problem mainly caused from queuing cells out of UITableView when you scroll cells get dequeued and therefore calling CellForRowAt so it reset the default data, in your case resetting the UILabel value again.

    In your case i recommend setting the timer out side that function/cell, so you can normally use that value without resetting.