为啥我在自定义单元格中的复选框在快速选择和滚动时显示不同的行为?

Posted

技术标签:

【中文标题】为啥我在自定义单元格中的复选框在快速选择和滚动时显示不同的行为?【英文标题】:Why my checkbox in custom cell shows different behaviour while selecting and scrolling in swift?为什么我在自定义单元格中的复选框在快速选择和滚动时显示不同的行为? 【发布时间】:2016-08-01 10:31:06 【问题描述】:

我有一个 xib 视图,其中我使用了一个 customcell xib 的tableView。在这个自定义单元格中,我有一个复选框按钮,其行为类似于使用自定义单元格进行选中和取消选中。但是,当我单击第一个单元格复选框时,勾选了第 9 个单元格的倍数,例如第 9 行单元格、第 18 行单元格,......也被勾选了。并且在滚动复选框勾选选项时,单元格之间会发生变化。我不知道为什么会这样..??

我已将单元格 xib 视图注册为:

override func viewDidLoad() 
    super.viewDidLoad()
    //Register custom cell
    let nib = UINib(nibName: "CustomOneCell", bundle: nil)
    AddOnTableView.registerNib(nib, forCellReuseIdentifier: "addoncell")
   
func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return 1

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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell:CustomOneCell = AddOnTableView.dequeueReusableCellWithIdentifier("addoncell") as! CustomOneCell
    let item: AddOnItems = ADDONITEMS[indexPath.row]
            cell.addOnName.text = item.name
            cell.addOnPrice.text = "£\(item.price!)"


    return cell

对于复选框,我添加了一个自定义类,如下所示:

var isCheckedAddOnGlobal = Bool()
class AddOnCheckBox: UIButton 


let checkedImage = UIImage(named: "checkboxredtick.png")! as UIImage
let unCheckedImage =  UIImage(named:"checkbox untick.png")!as UIImage

//bool property
var ischecked:Bool = false
    didSet
        //print(ischecked)
        if ischecked == true
            self.setImage(checkedImage, forState: .Normal)


        else
            self.setImage(unCheckedImage, forState: .Normal)
        
    


override func awakeFromNib() 
    self.addTarget(self, action:#selector(CheckBox.buttonClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
    self.ischecked = false


func buttonClicked(sender: UIButton) 

    if (sender == self) 
        if ischecked == true
            ischecked = false
            isCheckedAddOnGlobal = false

        else
            ischecked = true
            isCheckedAddOnGlobal = true

        

    

    
 

【问题讨论】:

为什么你不使用 didSelectCell 方法而不是添加奇怪的目标,只需在 didSelectCell 方法中使用 buttonClicked,这会有所帮助 我的按钮在自定义单元格中,所以我想我没有添加目标,如果单元格内容在另一个具有超类 UITableViewCell@Lu_ 的 swift 文件上,我怎么能设置按钮单击的任何操作? 检查我的答案,不要使用单元格作为按钮,它有自己的点击和其他操作方法 【参考方案1】:

发生这种情况是因为您正在重用 TableViewCell,要解决您的问题,您可以尝试类似的方法,首先创建一个 Int 数组,为您提供选定的行,然后在 cellForRowAtIndexPath 方法中使用该数组。

var selectedItems = [Int]()

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell:CustomOneCell = AddO nTableView.dequeueReusableCellWithIdentifier("addoncell") as! CustomOneCell
    let item: AddOnItems = ADDONITEMS[indexPath.row]
    cell.addOnName.text = item.name
    cell.addOnPrice.text = "£\(item.price!)"
    cell.checkBoxBtn.tag = indexPath.row
    if (selectedItems.contains(indexPath.row)) 
        cell.checkBoxBtn.setImage(UIImage(named:"checkbox untick.png"), forState: .Normal)
    
    else 
        cell.checkBoxBtn.setImage(UIImage(named: "checkboxredtick.png"), forState: .Normal)
    
    cell.checkBoxBtn.addTarget(self, action:#selector(self.buttonClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
    return cell


func buttonClicked(sender: UIButton) 
     if (self.selectedItems.contains(sender.tag)) 
          let index = self.selectedItems.indexOf(sender.tag)
          self.selectedItems.removeAtIndex(index)
     
     else 
          self.selectedItems.append(sender.tag)
     
     self.tableView.reloadData()

【讨论】:

您已在同一位置添加了所有按钮操作。我想使用我在代码中使用的按钮的自定义类。 您不能使用旧方法来完成此操作,因为当您重复使用 UITableViewCell 时,它将无法使用它。 代码工作正常。但我需要根据选择复选框来实现很多东西。所以你能否让我理解 buttonClicked 中发生的事情 点击按钮时我们检查选中的复选框是否已经在数组中,如果它在里面意味着我们需要取消选中它,所以我们从数组中删除对象,如果数组没有包含对象意味着我们需要检查按钮,因此我们在该数组中添加行。 好的。例如,如果我必须根据基于复选框计数的一些限制来设置复选框选择..我应该在哪里定义它..查看旧代码而不是你能理解的..pastie.org/10925906【参考方案2】:

最好的方法是选择单元格调用

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomOneCell
    cell.buttonClicked()

并将 buttonClicked 方法更改为

func buttonClicked() 
...

【讨论】:

【参考方案3】:

我会创建一个包含产品信息和布尔值的对象来检查产品是否已被选中。

如果您这样做,复选标记将显示正确。当您在 tableview 上滚动时,它会在每次显示新单元格时加载数据。

现在,它只知道索引等9被选中,当你向下滚动并加载新单元格时,索引9将再次被自动选中。

试试这样的:

例子

class Product 
var productName = "Test"
var isSelected: Bool = false

在你的 cellForRowAtIndexPath 下

if product.isSelected == true 
    cell.checkBoxBtn.setImage(UIImage(named:"checkbox untick.png"), forState: .Normal)
 else 
    cell.checkBoxBtn.setImage(UIImage(named: "checkboxredtick.png"), forState: .Normal)

【讨论】:

请发一些样品 把你的项目上传到github,这样帮忙就容易多了 我贴了一个小例子。希望对你有帮助

以上是关于为啥我在自定义单元格中的复选框在快速选择和滚动时显示不同的行为?的主要内容,如果未能解决你的问题,请参考以下文章

按下单元格中的按钮时显示新视图

如何在自定义单元格中同步选择文本视图的事件?

图像的滚动视图在自定义表格视图单元格中不起作用

UIButton 在自定义单元格中更改

在自定义单元格中聚焦 UITextfield

快速滚动ios时自定义单元格中的UITextField值出现问题