gpt4 book ai didi

ios - UITableView 更新错误的单元格

转载 作者:行者123 更新时间:2023-11-28 06:15:28 25 4
gpt4 key购买 nike

我有一个包含多个同一类单元格的 Tableview。在单元内更改开关时,应下载特定文件。

实际行为:正确的开关正在改变它的状态,即使在滚动时它也会被存储,所以这不是问题。 countryDesignator 在开始下载时是正确的,完成后也是正确的文件,但是当文件存储时,它使用了错误的 countryDesignator,并且进度条也是错误的。在这种特殊情况下,点击加拿大将导致下载文件 [..]ca_asp.aip 并且加拿大单元格中的开关发生变化,但奥地利单元格的进度条正在移动并且存储的文件名为 at_asp_aip。

example

代码:

var countrySettings : [countryOptions] = [countryOptions(name: "Austria", isEnabled: false, progress: 0.0, filename: "at"),
countryOptions(name: "Australia", isEnabled: false, progress: 0.0, filename: "au"),
countryOptions(name: "Brazil", isEnabled: false, progress: 0.0, filename: "br"),
countryOptions(name: "Canada", isEnabled: false, progress: 0.0, filename: "ca"), ...]

var downloadCount : Int = 0

class CountrySettings: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var countryTableView: UITableView!

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "Country") as! countryCell
cell.countryName.text = countrySettings[indexPath.row].name
cell.countrySwitch.isOn = countrySettings[indexPath.row].isEnabled
cell.countryDesignator = countrySettings[indexPath.row].filename
return cell
}

class countryCell: UITableViewCell, URLSessionDownloadDelegate,UIDocumentInteractionControllerDelegate {
@IBOutlet weak var countrySwitch: UISwitch!
@IBOutlet weak var countryName: UILabel!
var countryDesignator : String = "ad"

@IBAction func didChangeSwitchValue(_ sender: UISwitch) {
guard let indexPath = self.indexPath else { return }
downloadCount = 0
print(countryDesignator) // prints correct Designator
startDownloading()
}

func startDownloading () {
guard let indexPath = self.indexPath else { return }
countrySettings[indexPath.row].isEnabled = countrySwitch.isOn
DispatchQueue.main.async {
print(self.countryDesignator) // prints correct Designator
downloadCount += 1
if downloadCount == 1 {
let url = URL(string: "https://www.blablabla.com/" + self.countryDesignator + "_asp.aip")!
self.downloadTask = self.defaultSession.downloadTask(with: url)
self.downloadTask.resume()
}
}
}


// MARK:- URLSessionDownloadDelegate
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
print(countryDesignator) // prints WRONG!
print("File download succesfully")
let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
let documentDirectoryPath:String = path[0]
let fileManager = FileManager()
var destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appendingFormat("/" + countryDesignator + "_asp.aip"))

if downloadCount == 2 {
destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appendingFormat("/" + countryDesignator + "_wpt.aip"))
}
if fileManager.fileExists(atPath: destinationURLForFile.path){
showFileWithPath(path: destinationURLForFile.path, completePath: destinationURLForFile)
print(destinationURLForFile.path)
}
else{
do {
try fileManager.moveItem(at: location, to: destinationURLForFile)
// load data into database
showFileWithPath(path: destinationURLForFile.path, completePath: destinationURLForFile)
}catch{
print("An error occurred while moving file to destination url")
}
}
}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

DispatchQueue.main.async {
print(self.countryDesignator) // prints WRONG
guard let indexPath = self.indexPath else { return }
self.progress.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true)
countrySettings[indexPath.row].progress = self.progress.progress
}
}


func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
downloadTask = nil
progress.setProgress(0.0, animated: true)
if (error != nil) {
print("didCompleteWithError \(error?.localizedDescription ?? "no value")")
}
else {
print("The task finished successfully")
print(downloadCount)
if downloadCount == 1 {
startDownloading()
}
}
}

override func awakeFromNib() {
super.awakeFromNib()
let backgroundSessionConfiguration = URLSessionConfiguration.background(withIdentifier: "backgroundSession" + countryDesignator)
defaultSession = Foundation.URLSession(configuration: backgroundSessionConfiguration, delegate: self, delegateQueue: OperationQueue.main)
progress.setProgress(0.0, animated: false) // This is working correctly
}
}

最佳答案

这是一个常见问题。因为 UITableViewCell可重用,所以你保存了单元格,但是单元格在滚动时会呈现不同的数据源

您不应该保存单元格,而是根据数据源记录您正在下载的内容。

    func startDownloading () {
guard let indexPath = self.indexPath else { return }
countrySettings[indexPath.row].isEnabled = countrySwitch.isOn
countrySettings[indexPath.row].isDownloading = true
DispatchQueue.main.async {
print(self.countryDesignator) // prints correct Designator
downloadCount += 1
if downloadCount == 1 {
let url = URL(string: "https://www.blablabla.com/" + self.countryDesignator + "_asp.aip")!
countrySettings[indexPath.row].downloadTask = self.defaultSession.downloadTask(with: url)
countrySettings[indexPath.row].downloadTask.resume()
}
}
}

并且始终将 countryDesignator 更改为呈现此下载数据源的单元格。

关于ios - UITableView 更新错误的单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45266472/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com