UITableViewCell 重复值

Posted

技术标签:

【中文标题】UITableViewCell 重复值【英文标题】:UITableViewCell duplicates values 【发布时间】:2019-01-21 10:30:03 【问题描述】:

我正在使用 Firebase 和外部 API 来获取 UITableView 的数据。 一般我都有这个代码。

public static func getUserLayers(completion: @escaping ()->Void)
    Firestore.firestore().collection("layers").whereField("uid", isEqualTo: (Auth.auth().currentUser?.uid)!).addSnapshotListener  (snapshot, error) in
        if error == nil 
            self.layers.removeAll()
            if let snap = snapshot?.documents 
                for doc in snap 
                    let data = doc.data()
                    let provider = data["layerprovider"] as! Int
                    if(provider != 0)
                        Alamofire.request("\(self.providerBaseUrl)\(String(describing: provider))").responseString  (response) in
                            if let resp = response.value 
                                let json = JSON(parseJSON: resp)
                                let logo = json["logo"]["medium"]["url"]
                                let blue = json["bg"]["blue"].intValue
                                let green = json["bg"]["green"].intValue
                                let red = json["bg"]["red"].intValue
                                self.layers.append(
                                    LayerInfo(ean: data["ean"] as! String, name: String(describing: data["name"]), logo: Provider.getLogo(imageUrl: "\(logo)"), bgR: red, bgG: green, bgB: blue, provider: json)
                                )
                            
                            completion()
                        

                    else
                        self.layers.append(
                            LayerInfo(ean: data["ean"] as! String, name: String(describing: data["name"]), logo: UIImage(), bgR: 0, bgG: 0, bgB: 0)
                        )
                    
                
                completion()
            
        
    

这是从 Firebase 获取数据的代码,如果它不等于“0”,则尝试获取提供程序。

这里的ViewController是:

LayerService.getUserLayers 
            self.layers = LayerService.layers
            self.tableView.reloadData()
        

还有 UITableViewCell:

DispatchQueue.main.async 
        for subview in self.subviews
            subview.removeFromSuperview()
        

        let layer = Layer(frame: CGRect(x: 10, y: 5, width: self.bounds.width - 40, height: 210), bg: self.bg, logo: self.logo, ean: self.ean)
        self.addSubview(layer)
    

但问题在于,在重复使用单元格时 - 它会重复第 1 和第 5 个单元格、第 2 和第 6 个单元格等。 甚至当我单击单元格 #1 时,它也会在单元格 #5 处翻转图层(因为我在图层 UIView 子类中点击了翻转)...

我哪里错了?

谢谢。任何建议表示赞赏。

我的cellForRowAt 方法

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell  
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! LayersTableViewCell 
    cell.logo = self.layers[indexPath.row].logo 
    cell.bg = self.layers[indexPath.row].bg 
    cell.ean = self.layers[indexPath.row].ean 
    return cell 

【问题讨论】:

请显示您的 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 方法 @Andrey Chernukha func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! LayersTableViewCell cell.logo = self.layers[indexPath.row].logo cell.bg = self.layers[indexPath.row].bg cell.ean = self.layers[indexPath.row].ean return cell 【参考方案1】:

请在解析数据后重新加载您的表格视图

public static func getUserLayers(completion: @escaping (AnyObject)->Void)
Firestore.firestore().collection("layers").whereField("uid", isEqualTo: (Auth.auth().currentUser?.uid)!).addSnapshotListener  (snapshot, error) in
        if error == nil 
            self.layers.removeAll()
            if let snap = snapshot?.documents 
                for doc in snap 
                    let data = doc.data()
                    let provider = data["layerprovider"] as! Int
                    if(provider != 0)
                        Alamofire.request("\(self.providerBaseUrl)\(String(describing: provider))").responseString  (response) in
                            if let resp = response.value 
                                let json = JSON(parseJSON: resp)
                                let logo = json["logo"]["medium"]["url"]
                                let blue = json["bg"]["blue"].intValue
                                let green = json["bg"]["green"].intValue
                                let red = json["bg"]["red"].intValue
                                self.layers.append(
                                    LayerInfo(ean: data["ean"] as! String, name: String(describing: data["name"]), logo: Provider.getLogo(imageUrl: "\(logo)"), bgR: red, bgG: green, bgB: blue, provider: json)
                                )
                            
                            completion(["res": self.layers, "stats":1] as AnyObject?)
                        

                    else
                        self.layers.append(
                            LayerInfo(ean: data["ean"] as! String, name: String(describing: data["name"]), logo: UIImage(), bgR: 0, bgG: 0, bgB: 0)
                        )
                    
                
                completion(["res": self.layers, "stats":1] as AnyObject?)
            
        
    


然后修改:

LayerService.getUserLayers (withCompletionHandler:AnyObject?) in
        let dictResponse = withCompletionHandler as! Dictionary<String, Any>
            let isSuccess : Int = dictResponse["stats"] as! Int

            if isSuccess == 1
              self.layers = LayerService.layers
              DispatchQueue.main.async 
                self.tableView.reloadData()
              
            

    

它可能对你有帮助。谢谢。

【讨论】:

这可能有问题,因为:1)我有 Alamofire.request 不在 tableView 所在的视图中。 2)你确定当我为tableView获取100个项目时 - 我需要在每个项目之后重新加载数据()?谢谢。 没有。在数组中添加所有数据后,您重新加载表格视图。 稍微修改了你的答案,因为完成处理程序有点乱,但我想我明白了你想告诉我的主要想法。不幸的是,UITableView 在更改后表现相同:( 还有一件事可能会有所帮助 - 当我在每个 UITableViewCell 上使用简单的 textLabel 时,它只显示接收到的数据中的名称而不是复杂的子层(内部还有 2 个子层),它的效果非常好!所以对我来说,它看起来更像是某种缓存,而不是调度命令。

以上是关于UITableViewCell 重复值的主要内容,如果未能解决你的问题,请参考以下文章

在自定义 UITableViewCell UITextField 中输入的值转换为其他字段

如何返回一个零自定义 UITableViewCell

UITableViewCell 重复值

将子视图添加到 UITable

保存后 UITableViewCell 和 Coredata 上的 UIImage 的方向发生了变化

UITableViewCell错误:此类不符合键值编码[重复]