Swift - 第二次加载后 Tableview 无法正确重新加载

Posted

技术标签:

【中文标题】Swift - 第二次加载后 Tableview 无法正确重新加载【英文标题】:Swift - Tableview won't reload correctly after loading for the second time 【发布时间】:2019-07-30 19:12:48 【问题描述】:

我对我的 Tableview 的反应有些困惑。我的问题是 Tableview 显示的顺序不是 Dictionary 而不是我打印 Dictionary 时的顺序。当我打印 Dictionary 时,一切似乎都很好,但是当我查看手机时,tableview 再次以随机顺序显示单元格。

首先我获取 JSON。

    var Aanbiedingen_bieren = [Aanbiedingen_bier]()
    var Aanbiedingen_bieren_Filter = [Aanbiedingen_bier]()

获取数据。

func fetchData() 
    Aanbiedingen_bieren_Filter.removeAll()
    Aanbiedingen_bieren.removeAll()
    let url_Aanbiedingen_bier = URL(string: "\(Firebase_url)")
    let downloadURL = url_Aanbiedingen_bier
    URLSession.shared.dataTask(with: downloadURL!)  data, urlResponse, error in
        let data = data
        print("downloaded")
        do
        
            let decoder = JSONDecoder()
            let downloadedBiers = try decoder.decode(SheetJS.self, from: data!)
            self.Aanbiedingen_bieren = downloadedBiers.SheetJS

            for jsonData in self.Aanbiedingen_bieren 
                let Soort = jsonData.Title
                if self.Soort_Bier == "Alles" 
                    self.Aanbiedingen_bieren_Filter.append(jsonData)
                else
                    if self.Soort_Bier == "Krat" 
                        if Soort.contains(word: "Krat") 
                            self.Aanbiedingen_bieren_Filter.append(jsonData)
                        
                    
                    if self.Soort_Bier == "Fles" 
                        if Soort.contains(word: "Fles") 
                            self.Aanbiedingen_bieren_Filter.append(jsonData)
                        
                    
                
            
            self.Aanbiedingen_bieren_Filter = self.Aanbiedingen_bieren_Filter.sorted(by: $0.Voor_prijs.compare($1.Voor_prijs, options: .numeric) == .orderedAscending)
            print(self.Aanbiedingen_bieren_Filter)
            DispatchQueue.main.async 
                self.tableView.reloadData()
            
         catch 
            print(error)
        
    .resume()

代码第一次运行Soort_Bier = "Alles"。点击按钮后,Soort_Bier 将变为Soort_bier = "Krat"。第二次加载数据后,我首先想过滤数据。我通过实现一个 if 语句来完成此操作,该语句检查 JSON 的标题是否在字符串中有特定的单词,如果有,则将其附加到另一个数组。在那之后,我想对价格进行排序。排序完成后,我想打印 Dictionary 以查看排序是否正确。情况似乎仍然如此。然后我想重新加载tableView,这样所有的单元格都会显示出来,这里出了点问题。当我想第二次加载字典时,它似乎没有正确地重新加载 tableView。

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return Aanbiedingen_bieren_Filter.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Aanbiedingen_bieren_Cell", for: indexPath) as! Aanbiedingen_bieren_Cell

        let Aanbiedingen_bier = self.Aanbiedingen_bieren_Filter[indexPath.row]
        cell.Aanbiedingen_bier = Aanbiedingen_bier

        return cell
    

结构:

struct SheetJS: Codable 
    var SheetJS: [Aanbiedingen_bier]

    init(SheetJS: [Aanbiedingen_bier]) 
        self.SheetJS = SheetJS
    


struct Aanbiedingen_bier: Codable 
    let Logo_Image: String
    let Van_prijs: String
    let Voor_prijs: String
    let Beschrijving: String
    let Item_Image: String
    let Title: String
    let Bestel_Online_link: String
    let Footer_item: String
    let Item_1: String
    let Item_2: String

    init(Logo_Image: String, Item_Image: String, Van_prijs: String, Voor_prijs: String, Beschrijving: String, Title: String, Item_1: String, Item_2: String, Bestel_Online_link: String, Footer_item: String) 
        self.Logo_Image = Logo_Image
        self.Title = Title
        self.Item_Image = Item_Image
        self.Beschrijving = Beschrijving
        self.Van_prijs = Van_prijs
        self.Voor_prijs = Voor_prijs
        self.Item_1 = Item_1
        self.Item_2 = Item_2
        self.Bestel_Online_link = Bestel_Online_link
        self.Footer_item = Footer_item

    

JSON:


  "SheetJS": [
    
      "Logo_Image": "https://www.biernet.nl/images/winkel/17335-agrimarkt.gif",
      "Van_prijs": "€16,99",
      "Voor_prijs": "€10,49",
      "Beschrijving": "Krat 24x0,30",
      "Item_Image": "https://www.biernet.nl/images/soort/23026-grolsch%20krat%20normale%20flesjes%2030%20cl.png",
      "Title": "Grolsch Premium Pilsener",
      "Bestel_Online_link": "",
      "Footer_item": "t/m zaterdag 3 augustus",
      "Item_1": "€6,50 korting (38%)",
      "Item_2": "€1,46 per liter"
    ,//Some more data
  ]

只打印字典的价格:

€5,39
€5,94
€6,39
€6,39
€7,64
€16,19

Result

如果您需要更多信息或代码,请告诉我。

【问题讨论】:

“正确”重新加载是什么意思?您正在清除数据并重新加载... 当我print(self.Aanbiedingen_bieren_Filter)时,它会正确显示(价格从低到高),但tableView会显示另一个订单(见图)。这就是为什么我认为它没有正确加载,或者它一定是我不知道的其他东西。 对,但是您在哪里调用这种数据重新加载?第二次…… @Dani010- 请在主线程中执行整个 do 块代码。而不是只重新加载表数据 @SalvadorMolina 我将第一次调用名为:fetchData() 的函数。当您按下按钮时,Soort_Bier 将更改为 Soort_Bier = "Prijs",之后将第二次调用名为:fetchData() 的函数。 【参考方案1】:

这是因为 Dictionary 中的项目是随机排序的。

如果你想订购它,你应该使用“设置”另一个有序的集合类型。

或查看下面的 Apple 文档

Apple Docs:字典中键值对的顺序在突变之间是稳定的,但在其他方面是不可预测的。如果您需要有序的键值对集合并且不需要 Dictionary 提供的快速键查找,请参阅 KeyValuePairs 类型以获取替代方案。

【讨论】:

嗨,我还在努力让它工作。我似乎无法让我的代码与“设置”一起使用。请给我更多解释如何让它工作? 嗯...我再次查看您的代码,它不是字典类型。所以我认为重新加载 tableview 不能正常工作。你有没有在 tableView cellForRowAt 方法中打印 Aanbiedingen_bieren_Filter ?【参考方案2】:

我认为您没有错误地使用数据收集。您应该使用数组来订购。因为字典在没有定义排序的集合中存储了相同类型的键和相同类型的值之间的关联。与数组不同,字典没有指定的顺序。

点击here!快速阅读有关数据收集的信息

【讨论】:

您好,感谢您的反应。似乎该网址不起作用。能更新一下网址吗? 谢谢。我有个问题。你说如果我想在我的 tableView 中有一个特定的顺序,我需要使用一个数组。但是如何将 JSON 数据设置为最好的数组?

以上是关于Swift - 第二次加载后 Tableview 无法正确重新加载的主要内容,如果未能解决你的问题,请参考以下文章

进行第二次 Json 调用 Swift 3 后如何在 UITableview 中重新加载数据

Swift UIViewController tableView.reloadData nil 在第二次调用时包装

Swift 5 - 用户第二次单击标签栏按钮后,需要帮助在视图控制器 1 上重新加载 Web 视图

第二次推送视图控制器xamarin ios后需要触摸以与tableview交互

关闭块不会在第二次 swift3 上重新加载表

Swift:在警报视图中按下按钮后,tableView 不会重新加载数据