滚动时在最后一个 tableView 单元中添加按钮显示两次
Posted
技术标签:
【中文标题】滚动时在最后一个 tableView 单元中添加按钮显示两次【英文标题】:adding Button in last tableView Cell shown twice when scrolling 【发布时间】:2018-01-04 17:41:37 【问题描述】:使用 Swift4、ios11.2.1、Xcode9.2,
我成功地将自定义按钮添加到 tableView 的最后一个单元格。 (该按钮用于在 tableView 中添加单元格 - 这也可以正常工作......) - 参见 Screenshot-1。
但现在的问题是:当添加更多单元格时(即超过 tableView-height 的容量),并且如果您滚动到顶部,则会有第二个单元格显示此按钮 - 请参阅 Screenshot-2。
(见下面的代码......)
这是两张截图:
我怎样才能摆脱多余的按钮???? (似乎重复使用了一个单元格并且部分绘制了按钮。截止可以解释,因为最后一个单元格的高度大于其他单元格。但是,任何按钮中都不应该有部分按钮除了最后一个单元格之外的其他单元格......即使向上滚动)。
任何帮助表示赞赏!
这是我的代码(或它的摘录...):
override func viewDidLoad()
super.viewDidLoad()
// define delegates
self.fromToTableView.dataSource = self
self.fromToTableView.delegate = self
// define cell look and feel
self.addButton.setImage(UIImage(named: "addButton"), for: .normal)
self.addButton.addTarget(self, action: #selector(plusButtonAction), for: .touchUpInside)
//...
self.fromToTableView.reloadData()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
guard let resItems = resItems else
self.rowCount = 0
return 0
self.rowCount = resItems.count - 1
return resItems.count
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
if(indexPath.row == (self.rowCount))
return 160
else
return 120
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = fromToTableView.dequeueReusableCell(withIdentifier: "SettingsCell") as? SettingsCustomTableViewCell
// configure the cell
cell?.configureCell(tag: indexPath.row)
// fill cell-data
if let resItem = self.resItems?[indexPath.row]
cell?.connectionItem = resItem
// add addButton to last cell
if(indexPath.row == (self.rowCount))
// add addButton
cell?.contentView.addSubview(self.addButton)
// scroll to last cell (that was just added)
// First figure out how many sections there are
let lastSectionIndex = self.fromToTableView.numberOfSections - 1
// Then grab the number of rows in the last section
let lastRowIndex = self.fromToTableView.numberOfRows(inSection: lastSectionIndex) - 1
// Now just construct the index path
let pathToLastRow = IndexPath(row: lastRowIndex, section: lastSectionIndex)
// Scroll to last cell
self.fromToTableView.scrollToRow(at: pathToLastRow as IndexPath, at: UITableViewScrollPosition.none, animated: true)
return cell!
【问题讨论】:
我只需在footerView 中添加按钮,这样它就始终位于底部且更易于实现 是的,单元格被重复使用,并且您在单元格中一遍又一遍地添加按钮,如果不需要它们,请永远不要删除它们。我会在 Interface Builder 中使用按钮设计第二个单元格,并将其用于最后一个索引路径。并强制解开单元格as! SettingsCustomTableViewCell
。无论如何,在方法结束时你都会这样做,你会摆脱所有丑陋的问号。
【参考方案1】:
你已经弄清楚问题所在了:)
如你所说:
好像重用了一个单元格,部分绘制了按钮
这正是这里发生的事情。您有一个UITableViewCell
元素池,或者在您的情况下为SettingsCustomTableViewCell
。所以每当你说:
let cell = fromToTableView.dequeueReusableCell(withIdentifier: "SettingsCell") as? SettingsCustomTableViewCell
然后,顾名思义,您从UITableView
中取出一个可重复使用的单元格。
这也意味着,只要您重复使用 该 单元格的特定实例,您之前可能在单元格上设置的任何内容(例如您的按钮)都会保留在那里。
您可以(至少)通过三种方式解决此问题。
黑客
在您的tableView(_:cellForRowAt:indexPath:)
中,您有这个:
if(indexPath.row == (self.rowCount))
//last row, add plus button
您可以添加一个else部分并再次删除加号按钮:
if(indexPath.row == (self.rowCount))
//last row, add plus button
else
//not last row, remove button
正确的方式
UITableViewCell
具有 prepareForReuse
功能,正如文档所述:
如果一个 UITableViewCell 对象是可重用的——也就是说,它有一个重用标识符——这个方法在对象从 UITableView 方法返回之前被调用 dequeueReusableCell(withIdentifier:)
因此,这是您“重置”自定义表格视图单元格的地方。在您的情况下,您删除了加号按钮。
您似乎已经有一个自定义的UITableViewCell
,所以这应该是一个小改动。
页脚方式
正如@paragon 在他的评论中建议的那样,您可以创建一个UIView
并将其作为tableFooterView 添加到您的UITableView
。
let footerView = YourFooterViewHere()
tableView.tableFooterView = footerView
希望有帮助
【讨论】:
非常感谢 pbodsk 提供这些出色的解释!以上是关于滚动时在最后一个 tableView 单元中添加按钮显示两次的主要内容,如果未能解决你的问题,请参考以下文章