Timer
Sometimes we need to manage multiple timers in UICollectionView so if we recreate multiple timers then it will show wrong value so for this, we need to create a single Timer class for every single Cell, and also manage every refresh cell in UICollectionView.
for manage recreating or refreshing cell we need to follow some steps:
1: Create a dictionary of timers:
var timerLatestProduct = [Int:Timer]()
var timerCount:NSMutableArray = [100,100,100,100,100,100,100,100,100]
2: Now its time to add the timer in cell’s label.
here I have taken an array of value which contains a value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // register your cell and set cell.textLabel.text = "some value" cell.textlabel.tag = indexpath.row if timer[indexPath.row] == nil{ print("fisrt") timer[indexPath.row] = (Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runScheduledTask), userInfo: details, repeats: true)) }else{ print("second") let t:Timer = timer[indexPath.row]! t.invalidate() timer[indexPath.row] = (Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runScheduledTask), userInfo: details, repeats: true)) } } |
Here we are checking whether the timer is created or not and if we scroll the cell then “cellForItemAt” is called then we are re-creating the timer object by invalidating the previous one .
Note:
Here userinfo: we are sending the cell label or you can send cell also
Now its time to define the timer class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
func runScheduledTask(_ runningTimer: Timer) { var dict = runningTimer.userInfo as! [String:UILabel]; if let label:UILabel = (dict["cell"]) { label.text = "" var remainingSeconds:Double = timerCount.getTimer[label.tag].time remainingSeconds -= 1 if remainingSeconds == 0 || remainingSeconds < 0{ label.text = "" } else{ let formatter = DateComponentsFormatter() formatter.allowedUnits = [.day, .hour, .minute, .second] formatter.unitsStyle = .positional let formattedString = formatter.string(from: TimeInterval(remainingSeconds))! label.text = formattedString.uppercased() timerCount[label.tag] =remainingSeconds } } } |
Now we are handling the array of timer separately for every timer object.