UITableViewCell 类 2 函数中的 UIButton
Posted
技术标签:
【中文标题】UITableViewCell 类 2 函数中的 UIButton【英文标题】:UIButton in TableViewCell Calls 2 Functions 【发布时间】:2017-03-26 17:58:14 【问题描述】:即使在完全重写此视图控制器之后,我的表格视图的最后 2 个部分中的 2 个按钮仍然存在问题。我有 2 个按钮,其中一个在第 3 节中,另一个在第 4 节中(表格视图只有 5 个部分,所以这些是最后 2 个)这两个按钮在单击时具有相似的功能,它们向该部分添加了 1 个额外的项目。问题是,当我单击其中一个按钮时,它可以正常工作,直到我选择另一个(除了它们在同一个表视图中的事实之外,它们无论如何都没有连接),当我单击另一个时,它会将 1 添加到其部分,就像它一样应该然后将 1 添加到其他部分。我已经尝试检查目标的数量,看看是否可以将两个按钮的功能添加到其中一个,但即使我只有一个目标,两个功能仍然被调用......我已经尝试了我能想到的所有东西任何帮助将不胜感激(抱歉没有发布任何代码,它是一个非常复杂的 swift 文件,让我知道你想看到什么,我会编辑这个答案)。
编辑 - 这是我为 UITableViews cellForRowAt 的第 4 节给出的(cellForRowAt 中的第 3 节和第 4 节除了一些命名差异外是相同的)
else
if indexPath.row == 0
cell = tableView.dequeueReusableCell(withIdentifier: "Section Card", for: indexPath)
let positionsSectionCard = cell.contentView.viewWithTag(1) as! UILabel
positionsSectionCard.text = "Positions"
else if indexPath.row == 1
cell = tableView.dequeueReusableCell(withIdentifier: "Picker Cell", for: indexPath)
let positionPicker = cell.contentView.subviews[0].subviews[1].subviews[0] as! UIPickerView
let addPositionButton = cell.contentView.viewWithTag(4) as! UIButton
let positionList = Array(positions.keys).sorted()
var positionCounter = 0
var enabledPositionsCounter = 0
positionPicker.dataSource = self
positionPicker.delegate = self
while positionCounter < positionList.count
if positions[positionList[positionCounter]]!
enabledPositionsCounter = enabledPositionsCounter + 1
positionCounter = positionCounter + 1
if enabledPositionsCounter == positions.count
addPositionButton.isEnabled = false
addPositionButton.setTitleColor(UIColor.gray, for: .normal)
else
addPositionButton.isEnabled = true
addPositionButton.setTitleColor(UIColor.white, for: .normal)
addPositionButton.titleLabel?.numberOfLines = 2
addPositionButton.titleLabel?.textAlignment = NSTextAlignment.center
addPositionButton.setTitle("Add\nPosition", for: .normal)
addPositionButton.addTarget(self, action: #selector(addPosition), for: .touchUpInside)
else
cell = tableView.dequeueReusableCell(withIdentifier: "Item Card", for: indexPath)
let positionLabel = cell.contentView.viewWithTag(1) as! UILabel
let removePositionButton = cell.contentView.viewWithTag(2) as! UIButton
let positionList = Array(positions.keys).sorted()
var positionCounter = 0
var usedPositionsList: [String] = []
positionLabel.adjustsFontSizeToFitWidth = true
positionLabel.numberOfLines = 2
if eventSettingsTableView.numberOfRows(inSection: 4) < 4
while positionCounter < positionList.count
if positions[positionList[positionCounter]]!
positionLabel.text = positionList[positionCounter]
positionCounter = positionCounter + 1
else
while positionCounter < eventSettingsTableView.numberOfRows(inSection: 4)
if eventSettingsTableView.cellForRow(at: IndexPath(row: positionCounter + 2, section: 4))?.contentView.subviews[0].subviews[1].subviews[0] != nil
print((eventSettingsTableView.cellForRow(at: IndexPath(row: positionCounter + 2, section: 4))?.contentView.subviews[0].subviews[1].subviews[0] as! UILabel).text!)
usedPositionsList.append((eventSettingsTableView.cellForRow(at: IndexPath(row: positionCounter + 2, section: 4))?.contentView.subviews[0].subviews[1].subviews[0] as! UILabel).text!)
positionCounter = positionCounter + 1
positionCounter = 0
while positionCounter < positionList.count
if !usedPositionsList.contains(positionList[positionCounter]) && positions[positionList[positionCounter]]!
positionLabel.text = positionList[positionCounter]
positionCounter = positionCounter + 1
removePositionButton.addTarget(self, action: #selector(removePosition(_:)), for: .touchUpInside)
【问题讨论】:
没有更多信息是无法判断的。发布您的cellForRow(at:)
方法,如果您在 IB 中设置了单元原型,还显示您的表格视图单元的连接检查器的屏幕截图。 (可以将多个 IBAction 链接到一个按钮,这听起来像是对出了什么问题的一个很好的猜测。)
@DuncanC 我刚刚编辑了问题,如果这还不够,或者您需要澄清一些问题,请告诉我
您在这里多次将self
作为目标添加到按钮:removePositionButton.addTarget(self, action: #selector(removePosition(_:)), for: .touchUpInside)
当您将目标添加到按钮时,它不会删除以前添加的目标。您需要删除以前的目标。
@AdilSoomro 在发布此内容之前,我检查了目标的数量,并且每个按钮总是给我 1 个(假设它给我的值不正确)有什么方法可以快速删除按钮?
是的,UIButton 具有删除目标方法,将nil
作为参数传递将删除所有目标。 button.removeTarget(nil, action: nil, for: .allEvents)
【参考方案1】:
表格视图重用单元格。基本上,当单元格离开屏幕时,它会作为进入屏幕的单元被重用(如果它们具有相同的重用标识符)。每当表格视图需要一个单元格时,tableView(_:cellForRowAt:)
就会被多次调用。它甚至可以为同一个单元格多次调用(例如,如果它离开视野然后重新进入)。
此行或其他类似行正在向同一个按钮添加多个目标,该按钮已经是您在表格视图中的其他位置使用单元格时添加的先前目标。
removePositionButton.addTarget(self, action: #selector(removePosition(_:)), for: .touchUpInside)
您可能需要做的是在添加新目标之前删除目标,或者从tableView(_:cellForRowAt:)
中删除addTarget
调用。
查看UIControl
的文档,了解如何删除目标。
*提示:removeTarget(_:action:for:)
【讨论】:
如果我要检查 removePositionButton.allTargets 它会给我正确数量的当前目标吗? (我检查了 allTargets,它只显示了 1 个)【参考方案2】:如果你使用
button.addTarget(self, action: #selector(action1(_:)))
然后
button.addTarget(self, action: #selector(action2(_:)))
您将有 2 个与您的按钮相关联的操作,但只有 1 个目标。您为同一个目标添加了 2 个操作。因此,allTargets
属性仍将显示 1 个目标,即使有 2 个目标/操作连接到按钮。
如果您添加了具有相同目标和相同控制事件的多个操作,则应使用actions(forTarget:forControlEvent:)
查找它们。 (在你的情况下,actions(forTarget: self, forControlEvent:, .touchUpInside)
)
在您的cellForRow(at:)
方法中,您应该检查按钮上的目标/操作数量,如果操作计数为零,则仅向按钮添加新目标/操作,或者在添加新目标/操作之前删除所有目标/操作那些。
这里的经验法则是单元格会被回收,并且您应该始终假设返回的单元格cellForRow(at:)
具有上次使用时剩余的设置,并且您必须完全配置单元格中的每个视图。
【讨论】:
【参考方案3】:您的按钮是否可能(错误地)链接到多个操作?
【讨论】:
以上是关于UITableViewCell 类 2 函数中的 UIButton的主要内容,如果未能解决你的问题,请参考以下文章
Swift 中的自定义 UITableViewCell 注册类
自定义 uitableviewcell 中的 Uibuttons
两个类相互引用/从它的委托方法中的 UITextField 访问 UITableViewCell?