第一次后获取重复的表格视图单元格

Posted

技术标签:

【中文标题】第一次后获取重复的表格视图单元格【英文标题】:Getting duplicate tableview cells after first time 【发布时间】:2017-05-31 10:24:29 【问题描述】:

在我的应用程序中,有一个添加按钮,单击时将添加一个新的 tableviewcell。但是问题是我在第一次之后得到了重复的单元格。本质上,当我第二次点击时,我得到了 2 个重复项,第三次点击了 3 个,依此类推......请查看截图的图片:

上图是第一屏。单击“+”将添加一个新单元格,如下图所示:

现在保存后,

现在,如果我退出此视图并返回,再次单击添加并创建一个新单元格,它会给我上面段落中提到的重复项(即第二次为 2,第三次为 3,依此类推...)。 这是截图:

这是我正在使用的代码:

 @IBAction func addBasket(_ sender: UIButton) 

    let prefs         = UserDefaults.standard
    let status        = prefs.string(forKey: "status")

    if(status != nil)

        if( status == "pending")

            if(BasketItemList.count < 5 ) 

                self.addpost()

             else 


                let alert = SCLAlertView()
                alert.showWarning("Basket", subTitle: "Upgrade to add more")

            



         else 

            if(BasketItemList.count < 50 ) 

                self.addpost()

             else 

                let alert = SCLAlertView()
                alert.showWarning("Basket", subTitle: "Upgrade to add more")

            



        


    






func addpost() 

    let appearance = SCLAlertView.SCLAppearance(
        showCloseButton: false
    )

    let alert = SCLAlertView(appearance : appearance)
    let txt = alert.addTextField("Enter name")
    alert.addButton("Save") 

        if txt.text?.characters.count != 0 

            let basketname : String = txt.text!

            let userID = FIRAuth.auth()?.currentUser?.uid

            let postitem : [String :AnyObject] = ["userid" : userID! as AnyObject , "basketname" : basketname as AnyObject ]

            let dbref = FIRDatabase.database().reference()
            dbref.child("BasketList").childByAutoId().setValue(postitem)

            self.Basketdata2()



            let appearance = SCLAlertView.SCLAppearance(
                kDefaultShadowOpacity: 0,
                showCloseButton: false
            )

            let alertView = SCLAlertView(appearance: appearance)
            alertView.showTitle(
                "Saved", // Title of view
                subTitle: "", // String of view
                duration: 2.0, // Duration to show before closing automatically, default: 0.0
                completeText: "Done", // Optional button value, default: ""
                style: .success, // Styles - see below.
                colorStyle: 0xA429FF,
                colorTextButton: 0xFFFFFF
            )




         else 


            let alert = SCLAlertView()
            alert.showError("Oops!", subTitle: "Basket name should not be empty")

            self.tableviewbasket.reloadData()

        

    
    alert.addButton("Cancel")


    
    alert.showEdit("Add basket", subTitle: "Please enter your basket name")






func Basketdata2() 
    HUD.show(.labeledProgress(title: "Loading...", subtitle: ""))

    let databaseref = FIRDatabase.database().reference()
    var userID = FIRAuth.auth()?.currentUser?.uid

    if userID == nil 

        userID = userfbid
    

    databaseref.child("BasketList").queryOrdered(byChild: "userid").queryEqual(toValue: userID!).observeSingleEvent(of: .value, with:  (snapshot) in

        if snapshot.exists() 

            self.tableviewbasket.backgroundView = nil;
            HUD.hide()

          else 

            HUD.hide()


            self.tableviewbasket.setContentOffset(CGPoint(x : 0, y: -98), animated: true)


            if (self.BasketItemList.count == 0) 

                // tableView is empty. You can set a backgroundView for it.
                let label = UILabel(frame: CGRect(x: 5, y: 0, width: self.tableviewbasket.bounds.size.width, height:self.tableviewbasket.bounds.size.height))
                label.text = "The best preparation for tomorrow \n is doing your best today.\n Please create your first basket."
                label.textColor = UIColor.black;
                label.textAlignment = .center
                label.numberOfLines = 4
                label.sizeToFit()
                label.font = UIFont(name: "AvenirNext-Regular", size: 16.0)
                self.tableviewbasket.backgroundView = label;
                self.tableviewbasket.separatorStyle = .none;

            

        

    )



  func Basketdata() 

    HUD.show(.labeledProgress(title: "Please wait...", subtitle: ""))

    self.BasketItemList.removeAll()
    self.Basketid.removeAll()

    let databaseref = FIRDatabase.database().reference()
    let userID = FIRAuth.auth()?.currentUser?.uid

    databaseref.child("BasketList").queryOrdered(byChild: "userid").queryEqual(toValue: userID!).observeSingleEvent(of: .value, with:  (snapshot) in

        if snapshot.exists() 

            databaseref.child("BasketList").queryOrdered(byChild: "userid").queryEqual(toValue: userID!).observe(.childAdded, with: 
                (snapshot) in



                if let dictionary = snapshot.value as? [String : AnyObject] 


                    let basketitem = BasketList(text : "")
                    basketitem.setValuesForKeys(dictionary)

                    self.BasketItemList.append(basketitem)
                    self.Basketid.append(snapshot.key)
                    DispatchQueue.main.async 

                        if !self.BasketItemList.isEmpty 

                            HUD.hide()
                            self.tableviewbasket.reloadData()

                        

                    


                 else 

                    self.tableviewbasket.reloadData()
                    HUD.hide()
                


            )




          else 

            if (self.BasketItemList.count == 0) 

                // tableView is empty. You can set a backgroundView for it.
                let label = UILabel(frame: CGRect(x: 5, y: 0, width: self.tableviewbasket.bounds.size.width, height:self.tableviewbasket.bounds.size.height))
                label.text = "The best preparation for tomorrow \nis doing your best today"
                label.textColor = UIColor.black;
                label.textAlignment = .center
                label.numberOfLines = 2
                label.sizeToFit()
                label.font = UIFont(name: "AvenirNext-Regular", size: 16.0)
                self.tableviewbasket.backgroundView = label;
                self.tableviewbasket.separatorStyle = .none;

            


            HUD.hide()


        

    )





有人可以帮助我了解我的代码有什么问题吗?谢谢!

编辑:我没有运气就引用了这个帖子:Getting duplicate cells with UITableViewController cellForRowAtIndexPath

编辑 2:此外,当我离开该视图并转到同一视图时,重复值将消失。

编辑 3:尝试了答案但没有成功。

【问题讨论】:

添加警报显示警告确定操作。 你的 Firebase 数据库还好吗? 是的,firebase DB 工作正常。 我是否必须为每个警报添加 ok 操作?你也可以让我知道那会做什么吗?谢谢 实际上,还有另一个视图控制器执行相同的操作。但是,我们没有收到任何错误。 【参考方案1】:

按照以下步骤操作:

    当您从 firebase db 获取数据时,首先删除您在 cellForRow 方法中使用的数组所有对象。在你的情况下,我认为它应该是 Bucket 数组(不确定)。

    将数据分配给您的对象

    重新加载表格视图。

数据复制的原因。

让您的存储桶有 2 个值,并将其存储在数据库中。当您从数据库中获取数据时,它会为您提供所有值,即 1、2、3。现在您添加这些,您的数组将是 1,2,1,2,3。

这就是你的情况。

【讨论】:

所以我需要在这部分进行更改? func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: "webbasketcell", for: indexPath) as! WebbasketcellTableViewCell if BasketItemList.count > 0 let basketitem = self.BasketItemList[(indexPath as NSIndexPath).row] cell.label.text = basketitem.basketname return cell 什么是 BasketItemList?? 这是我们正在创建的单元格列表。另外,请注意,如果我离开视图并返回,重复值会消失。您认为这可能是刷新问题吗? if let dictionary = snapshot.value as? [String : AnyObject]之后写self.BasketItemList.removeAll() self.Basketid.removeAll(),不要使用dispatch重新加载tableView 我们试过了。新单元格将被覆盖。

以上是关于第一次后获取重复的表格视图单元格的主要内容,如果未能解决你的问题,请参考以下文章

滚动时显示重复数据的 CollectionView 单元格?

将 UITextView 作为第一响应者后,表格视图单元格不可选择

在表格视图单元格中双击应该在 didSelectRowAtIndexPath 之前 [重复]

如何从资产中获取不同的图像并将其分配给不同表格视图单元格中的图像视图

设置表格视图单元格的高度以匹配底部到标签栏顶部

ios - 单元格表格视图内的视图位置仅在滚动后才会更改