单元格中的选定按钮显示在重用单元格上 - 也使用 sender.tag 进行按钮区分

Posted

技术标签:

【中文标题】单元格中的选定按钮显示在重用单元格上 - 也使用 sender.tag 进行按钮区分【英文标题】:Selected button in cell is showing up on reuse cells - also using sender.tag for button distinction 【发布时间】:2015-08-19 02:47:09 【问题描述】:

我在一个表中有一堆行,每行包含 6 个 UIButton(它们是复选框图像)。我一开始只是试图让一个按钮在链接所有按钮之前工作,这有点工作。如果我单击它,代码会将图像更新为选中的框,并且如果我向下滚动并备份第一个单元格,则第一个框将是唯一选中的框。如果我反复上下滚动,它会随机取消选择第一个单元格第一个框。这是我的 ViewController 代码:

//
//  TestViewController.swift
//

import UIKit
import Parse



class TestViewController: UIViewController, UITableViewDelegate 

@IBOutlet var tableView: UITableView!


override func viewDidLoad() 
    super.viewDidLoad()



func numberOfSectionsInTableView(tableView: UITableView) -> Int 

    return 1


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    return 10




func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! protoCell

    configure(cell, forRowAtIndexPath: indexPath)

    cell.customIndexPath = indexPath

    return cell





func configure(cell: protoCell, forRowAtIndexPath indexPath: NSIndexPath) 

    if cell.selectedIndexPaths.containsObject(indexPath) 

        println("Contains")
        let image = UIImage(named: "checkedbox.png")
        cell.button.setImage(image, forState: .Normal)
        println(cell.selectedIndexPaths)

     else 

        println("Not Contains")
        let image = UIImage(named: "checkbox.png")
        cell.button.setImage(image, forState: .Normal)

    





override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.




我正在为我的 UITableViewCell 使用自定义可可类来控制表格,这里有代码:

//
//  protoCell.swift
//  ParseStarterProject
//

import UIKit

class protoCell: UITableViewCell 

var selectedIndexPaths = NSMutableSet()

var customIndexPath: NSIndexPath = NSIndexPath()

var isPressed = [1, 1, 1, 1, 1, 1]

@IBOutlet var button: UIButton!

@IBAction func buttonPressed(sender: AnyObject) 

    println(isPressed[sender.tag])

    if isPressed[sender.tag] == 1 

        isPressed[sender.tag] = 2
        let image = UIImage(named: "checkedbox.png")
        sender.setImage(image, forState: .Normal)
        selectedIndexPaths.addObject(customIndexPath)

     else 

        isPressed[sender.tag] = 1
        let image = UIImage(named: "checkbox.png")
        sender.setImage(image, forState: .Normal)
        selectedIndexPaths.removeObject(customIndexPath)

    

    println(isPressed)




我知道代码是错误的,因为我所看到的。除了第一个按钮之外的所有图像都在重复。我对 Objective-C 不太熟悉,所以有些搜索很困难。

任何帮助都会很棒!

【问题讨论】:

一个单元格中有多少个按钮? 一个单元格中有六个按钮 好的,现在我想你知道出了什么问题了。当您滚动时,实际上表格视图会尝试重新使用单元格,因此您会在此处看到不需要的行为。正确的方法是在单元格之外的单独数组中维护单元格状态。然后将其映射到给定行的单元格。数组中的行索引应该为右单元格获取正确的状态。 是的,这就是我试图做的,但没有奏效。您对我可以对上述代码进行哪些更改以使功能正常工作有任何见解吗? 提出一个简单的模型对象,称为 Config。让每个配置为给定单元保持 6 个按钮的状态。有一个包含 10 个配置对象的数组(你想要的 10 行)。现在确保给定行的单元格映射到此数组中的正确配置。在表视图控制器中维护此数组。每次配置单元格时,将正确的配置对象传递给它,并让它在按下按钮时修改此对象中的状态。 【参考方案1】:

请查看下面的框架代码(我只是在这里输入,未测试),它应该可以让您对需要做什么有一个公平的想法-

 class Config
      enum ButtonState : Int 
        case NoneSelected,
        case Button1Selected,
        case Button2Selected,
        case Button3Selected,
        case Button4Selected,
        case Button5Selected,
        case Button6Selected
      
       var buttonState : Int = . NoneSelected
    

//Within TableView controller, maintain an array of 10 such objects
var configs = [ButtonState(), ButtonState(), ButtonState(), ButtonState(), ButtonState(), ButtonState(), ButtonState(), ButtonState(), ButtonState(), ButtonState()]

//This is how you need to configure the cell now-
func configure(cell: protoCell, forRowAtIndexPath indexPath: NSIndexPath) 

  //First deselect all buttons
   DeselectAllButtons()

  //Get proper config object
   var config = configs[indexPath.row]
   //Maintain a ref to the config in the cell.
   self.config = config

   switch config. buttonState
   case . NoneSelected
    DeselectAllButtons()
   case let x where (x & Button1Selected) == true
     SelectButton(button1)
      case let x where (x & Button1Selected) == true
     SelectButton(button1)
   case let x where (x & Button2Selected) == true
     SelectButton(button3)
   case let x where (x & Button3Selected) == true
     SelectButton(button3)
   case let x where (x & Button4Selected) == true
     SelectButton(button4)
   case let x where (x & Button5Selected) == true
     SelectButton(button5)
   case let x where (x & Button1Selected) == true
     SelectButton(button6)
   default:
     DeselectAllButtons()
  
 

 //And your action in cell can be-
func buttonPressed(sender: AnyObject)
    switch sender
      case button1
      self.config.buttonState  |= .Button1Selected
      case button2
      self.config.buttonState  |= .Button2Selected
      case button3
      self.config.buttonState  |= .Button3Selected
      case button4
      self.config.buttonState  |= .Button4Selected
      case button5
      self.config.buttonState  |= .Button5Selected
      case button6
      self.config.buttonState  |= .Button6Selected
    


【讨论】:

以上是关于单元格中的选定按钮显示在重用单元格上 - 也使用 sender.tag 进行按钮区分的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Tableview 重用了一些单元格?

UIViewRepresentable 在 SwiftUI 中的列表单元格中的位置

在tableView中选择多个单元格并将另一个tableView单元格中的选定单元格显示为标签?

当点击单元格上的按钮时,将信息写入单元格中

我想在 tableview 单元格中显示文本字段数据,以替换 iphone 中单元格上的现有数据?

单击单元格本身而不是按钮时,(静态)单元格中的按钮会消失