为啥我的 Tableview 重用了一些单元格?
Posted
技术标签:
【中文标题】为啥我的 Tableview 重用了一些单元格?【英文标题】:Why my Tableview is reusing some cells?为什么我的 Tableview 重用了一些单元格? 【发布时间】:2016-10-01 02:05:49 【问题描述】:我有一个待办事项列表,我在同一个单元格中有一个标签和一个按钮,当我单击按钮时,更改该单元格的图像按钮,但是当我滚动表格视图时,相同的按钮会出现在其他单元格上, 是不会出现在未按下按钮的单元格中。
这是我的 cellForRowAtIndexPath 代码
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! TaskTableViewCell
cell.label.text = "Task Number: \(indexPath.row + 1)"
cell.btnFavorite.setImage(UIImage(named: "star"), forState: .Normal)
cell.btnFavorite.setImage(UIImage(named: "star-filled"), forState: .Selected)
cell.btnFavorite.addTarget(self, action: #selector(ListOfTasksViewController.addRemoveFavoriteList), forControlEvents: .TouchUpInside)
return cell
func addRemoveFavoriteList(sender : UIButton)
sender.selected = !sender.selected
自定义 TableViewCell 类:
import UIKit
class TaskTableViewCell: UITableViewCell
@IBOutlet weak var label: UILabel!
@IBOutlet weak var btnFavorite: FavoriteButton!
override func awakeFromNib()
super.awakeFromNib()
override func setSelected(selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
override func prepareForReuse()
super.prepareForReuse()
label.text = nil
btnFavorite.selected = false
视图控制器:
import UIKit
class ListOfTasksViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad()
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 20
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! TaskTableViewCell
cell.label.text = "Task Number: \(indexPath.row + 1)"
cell.btnFavorite.indexPath = indexPath.row
cell.btnFavorite.addTarget(self, action: #selector(ListOfTasksViewController.addRemoveFavoriteList), forControlEvents: .TouchUpInside)
return cell
func addRemoveFavoriteList(sender : FavoriteButton)
if sender.selected
sender.selected = false
else
sender.selected = true
let index = NSIndexPath(forRow: sender.indexPath, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(index) as! TaskTableViewCell
【问题讨论】:
这不是“问题”。重用是正确和可取的行为。毕竟,当您说tableView.dequeueReusableCellWithIdentifier
时,您就接受了它;你认为你在说什么?
按下单元格上的按钮时需要更新数据源。
【参考方案1】:
表格视图中的单元格被重复使用,因此当您向下滚动时,离开屏幕的单元格将被放置在队列的开头,然后再以不同的 indexPath 回到屏幕上。这可能会导致一些问题,因此您需要在自定义单元格类中覆盖 prepareForReuse
方法。
override func prepareForReuse()
super.prepareForReuse()
label.text = nil
btnFavorite.selected = false
【讨论】:
我这样做了,但是当我按下按钮并向下滚动时,更改的按钮不会出现在其他单元格中,(直到那里没问题)但是当我再次向上滚动时,按下的按钮不是同一张图,你知道为什么吗? 是的,因为该单元格已从屏幕上消失,因此已准备好重新使用,您需要确保您的数据源反映了通过单元格所做的任何更改。所以当你按下按钮时,你必须更新一个反映你的dataSource数组中对应对象的按钮状态的值。 然后当单元格返回屏幕时,在 cellForRowAtIndexPath 中,您需要根据反映按钮状态的对象的值设置按钮的selected
属性。
显示你的数据源和模型(如果有)
我刚刚创建了我的特定按钮:FavoriteButton : UIButton var isFavorite : Bool?但我没有编写具体的代码来解决这个问题,你有什么建议我怎样才能实现正确的数据源?【参考方案2】:
您需要在 cellforaRowAtIndexPath 中添加条件。
您需要在 Array 中添加标记来跟踪您的选择。 然后检查 cellforRowAtIndexPath。
例如
button.selected= No
if arrselectedIndexpath containObject:indexPath
button.selected =yes
【讨论】:
以上是关于为啥我的 Tableview 重用了一些单元格?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 tableView 中创建一个重用标识符而不是分配/初始化一个单元格?
当它们几乎没有区别时,我应该重用 tableView 单元格吗? [关闭]