Reputation: 757
I am making a Download manager for iOS but the issue is when the cells are more than they can fit into the screen after I scroll the screen it starts to give wrong data for example:
here is the code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("downloadCell", forIndexPath: indexPath) as! RCHDownloadAddictTableViewCell
updateCell(cell, forRowAt: indexPath)
return cell
}
func updateCell(cell: RCHDownloadAddictTableViewCell, forRowAt indexPath: NSIndexPath) {
let arrayInfo = downloadingArray[indexPath.row]
cell.cellProgressView.setProgress((arrayInfo.downloadProgress)!, animated: true)
cell.cellFileName.text = arrayInfo.fileName
cell.cellDownloadSpeed.text = String(format: "%.1fMB", (arrayInfo.downloadSize / 1000000))
cell.cellBlock = {
if (arrayInfo.downloadTask.state == NSURLSessionTaskState.Running) {
arrayInfo.downloadTask.suspend()
cell.cellButton.setImage(UIImage(named: "resume.png"), forState: UIControlState.Normal)
} else if (arrayInfo.downloadTask.state == NSURLSessionTaskState.Suspended) {
arrayInfo.downloadTask.suspend()
cell.cellButton.setImage(UIImage(named: "resume.png"), forState: UIControlState.Normal)
}
}
if (arrayInfo.didFinishDownload == true) {
cell.cellButton.hidden = true
cell.cellFinishIndicator.text = "Finished."
cell.cellProgressView.hidden = true
cell.cellFinishIndicator.hidden = false
} else {
cell.cellButton.hidden = false
cell.cellProgressView.hidden = false
cell.cellFinishIndicator.hidden = true
}
}
Update: See this video and focus on the first cell https://www.youtube.com/watch?v=S_PnAS5lb7s&feature=youtu.be
Upvotes: 0
Views: 3661
Reputation: 1266
You have used dequeueReusableCellWithIdentifier
for generate cell. By that method cell is reuse so,system use last generated cell.
For solve this problem you have to implemented else part like
cell.cellBlock = {
if (arrayInfo.downloadTask.state == NSURLSessionTaskState.Running) {
arrayInfo.downloadTask.suspend()
cell.cellButton.setImage(UIImage(named: "resume.png"), forState: UIControlState.Normal)
} else if (arrayInfo.downloadTask.state == NSURLSessionTaskState.Suspended) {
arrayInfo.downloadTask.suspend()
cell.cellButton.setImage(UIImage(named: "resume.png"), forState: UIControlState.Normal)
}else{
<Write default code here>
}
}
if (arrayInfo.didFinishDownload == true) {
cell.cellButton.hidden = true
cell.cellFinishIndicator.text = "Finished."
cell.cellProgressView.hidden = true
cell.cellFinishIndicator.hidden = false
} else {
cell.cellButton.hidden = false
cell.cellFinishIndicator.text = "Your text."
cell.cellProgressView.hidden = false
cell.cellFinishIndicator.hidden = true
}
Upvotes: 2
Reputation: 7466
Table view cells are reused via reuse queue. If you see let say 7 cells on screen at once, and when you scroll down (more finger up), then the cell that was moved out of bounds of the top edge, will be passed from the reused queue to show up on the bottom edge again. This cell is an initialised instance, furthermore you have set some concrete values for the public properties on that cell instance. It's an object that visually disappears but is still in memory and then it reappears. What you need to do is clean it up between the moment it disappears and when it reppaears.
The correct place and way to do this is this:
1) Visuals i.e. stuff related to UIView properties like .hidden
, .alpha
or .backgroundColor
or selection state should be reset to desired default state inside the prepareForReuse
overridden method inside your custom cell.Don't forget to call super.
2) For content related stuff like download progress I recommend to implement a custom public reset
method on the cell, inside the method do whatever you want that doesn't fall into prepareForReuse
group, and call this reset method inside cellForRowAtIndexPath immediately after you dequeue the cell from the queue.
Upvotes: 2