UITableViewCell 按钮单击在 UITableView 控件的多个部分中触发

TableViewCell button click firing in multiple sections of TableViewControl

有点奇怪,我似乎无法理解,所以我在 viewcontroller 中有一个 tableview 控件,在 tableviewcell 中我有一个使用委托的按钮。

因此,当单击按钮时,它会更改单元格的标签编号,并根据表格视图中单元格的标签更改按钮的图像。

但我遇到的问题是,当你 select 一个连续的按钮,即第一个按钮时,它似乎是 运行 为每个项目更改图像的功能节差不多。也就是说,选择第 5 个项目会将单元格中的每个第 5 个按钮更新为 selected 图像,这很奇怪。因为它几乎就像 tableview 被分成 5 个部分。

任何人都可以帮助防止这种行为,以便它只更改已按下的单元格中按钮的图标。

以下是我使用过的函数和一个 link 到 dropbox 上显示行为的视频 https://www.dropbox.com/s/a4aasti78872w6j/Help.mov?dl=0

代表

protocol StoryTableViewCellDelegate: class {

    func didBookmarkItem(cell: StoryTableViewCell, sender: AnyObject)

}

委托函数

@IBAction func bookmarkButtonDidTouch(sender: AnyObject) {

    bookmarkButton.animation = "pop"
    bookmarkButton.curve = "easeOut"
    bookmarkButton.duration = 0.5
    bookmarkButton.damping = 0.4
    bookmarkButton.velocity = 0.4
    bookmarkButton.animate()

    // The delegate which will handle bookmarking items
    delegate?.didBookmarkItem(self, sender: sender)

}

表视图中正在使用的函数class

// MARK: StoryTableViewDelegate
func didBookmarkItem(cell: StoryTableViewCell, sender: AnyObject) {

    // TODO: Implement bookmark functionality
    switch cell.bookmarkButton.tag {

    case 0:
        cell.bookmarkButton.setImage(UIImage(named: "Bookmark-Selected"), forState: UIControlState.Normal)
        cell.bookmarkButton.tag = 1


    case 1:
        cell.bookmarkButton.setImage(UIImage(named: "Bookmark-Not-Selected"), forState: UIControlState.Normal)
        cell.bookmarkButton.tag = 0
    default:
      break
    }
}

原因是,您可能会使用以下方法创建单元格:

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("cellID")
...

就像你应该做的那样。但是 dequeueReusableCellWithIdentifier 会重新使用单元格,因此如果您更改了单元格中的任何内容(如添加按钮),这些按钮仍将位于该回收单元格中。

因此您必须在每个单元格的 cellForRowAtIndexPath 中设置书签状态。

我曾经在向单元格添加按钮时遇到过类似的问题,并且在滚动单元格时自动有额外的按钮。所以我在重新使用单元格时做的第一件事就是删除所有按钮。

编辑示例代码

在你的

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)

您必须添加用于将按钮设置为所需状态的代码,它类似于您在 didBookMarkItem 中使用的代码:

switch myProperty {

    case 0:
        cell.bookmarkButton.setImage(UIImage(named: "Bookmark-Selected"), forState: UIControlState.Normal)
        cell.bookmarkButton.tag = 1


    case 1:
        cell.bookmarkButton.setImage(UIImage(named: "Bookmark-Not-Selected"), forState: UIControlState.Normal)
        cell.bookmarkButton.tag = 0
    default:
      break
    }

你当然需要一个 myProperty 变量,你也应该在你的 didBookMarkItem 中改变它

Table 视图单元格被重复使用。一旦您 select 一个单元格并更改其标签编号并将 selected 单元格滚动出 table 视图,它将再次用于在新的索引路径处显示一行出现的行。由于它的标签代表一个 selected 单元格的标签,因此它被突出显示。

尝试在 table 视图中查找有关单元格重用的信息。

您需要更改确定哪个单元格显示为 selected 的方法。将其作为 属性 添加到您的数据源中,并基于此将书签设置为 selected 或未 selected。

正如其他人所说,这是由于 table 单元重用。您希望 tableView(_:cellForRowAtIndexPath:) 方法始终更新模型中的单元格状态。您的书签状态应该是模型的 属性。当用户更改单元格的书签按钮状态时,新状态应反映在您的模型中。如果你做了这些事情,你的 table 细胞状态将永远是正确的。如果您还没有,最好总是定义一个自定义 UITableViewCell class,它包含 table 视图单元格中所有视图和控件的出口(您的书签按钮会有一个出口。)另外,在您的自定义单元格 class 中,当您捕获按钮选择时,您可以通过委托(正如您正在做的那样)或在细胞。我更喜欢闭包方法。如果您想查看一个有效的示例,请告诉我。

另外,取消标签。您不需要标签来跟踪您的书签按钮选择状态,除非它比您拥有的更多 shown/described。如果您按照我描述的方法进行操作,它就会得到处理。