如何快速修复 UITableCells 重复
Posted
技术标签:
【中文标题】如何快速修复 UITableCells 重复【英文标题】:How to fix UITableCells repeating in swift 【发布时间】:2015-07-01 04:43:10 【问题描述】:我知道这里已经有一些这样的问题,但我无法让它们中的任何一个起作用。基本上,我有一个 ui 表视图,每个单元格中有一个标签和一个开关。每 14 个单元格,开关就会重复一次。 (开关1的状态会改变开关14、28等...)
这是我的代码:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
// Configure the cell:
let cell = tableView.dequeueReusableCellWithIdentifier("CompanyCell", forIndexPath: indexPath) as! CompanyCell
println(companies.count)
cell.companyName.text = companies[indexPath.row]
return cell
31 个公司名称的数组被加载到单元格中:
[Apple Inc, American Express Co, ... , Exxon Mobil Corp, Dow Jones]
标签(公司名称)位于单元格的左侧,开关位于单元格的右侧。
那么我怎样才能让细胞停止相互重复使用呢?
【问题讨论】:
你需要在你的cellForRowAtIndexPath
方法中设置开关的状态。
@rmaddy 我建议您添加一个答案,以便可以接受。我相信这是正确的解决方案。
【参考方案1】:
现在您有一个模型来表示这个由 31 个公司名称组成的数组。我个人倾向于使用一组自定义的 Company
对象,这些对象不仅包含名称,还包含该公司的状态(即其开关是打开还是关闭):
class Company
let name: String
var state = false
init(name: String)
self.name = name
并且,我们还假设您已将单元格中的 UISwitch
连接到 CompanyCell
类中的 IBOutlet
:
class CompanyCell : UITableViewCell
@IBOutlet weak var companyName: UILabel!
@IBOutlet weak var companySwitch: UISwitch!
如果您有一个属性 companies
,它是这些 Company
对象的数组,那么您可以实现 UITableViewDataSource
方法:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return companies.count
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("CompanyCell", forIndexPath: indexPath) as! CompanyCell
let company = companies[indexPath.row]
cell.companyName.text = company.name
cell.companySwitch.on = company.state
return cell
您可能还想将单元格中开关的“值更改”操作连接到表格视图控制器中的一个方法,如果开关状态发生更改,该方法将更新模型:
@IBAction func didChangeValueInSwitch(sender: UISwitch)
let cell = sender.superview?.superview as! CompanyCell
let indexPath = tableView.indexPathForCell(cell)
let company = companies[indexPath!.row]
company.state = sender.on
【讨论】:
【参考方案2】:当您使用此行重复使用单元格时
let cell = tableView.dequeueReusableCellWithIdentifier("CompanyCell", forIndexPath: indexPath) as! CompanyCell
屏幕外未使用的单元格将返回给您。这个未使用的单元格将具有其属性 - 您的开关状态和根据其旧值设置的公司名称。
现在,您正在根据您的数据更新要设置的companyName
,这是完美的:
cell.companyName.text = companies[indexPath.row]
但是,这里您没有设置开关的状态,它仍然具有旧值。您需要维护开关状态的数据并在cellForRowAtIndexPath
方法中进行相应设置。像这样,switchStateArray
是您的开关状态的数据源:
cell.yourSwitch.on = switchStateArray[indexPath.row]
【讨论】:
【参考方案3】:如果 UITableCells imageview 重复,使用函数 func prepareForReuse()
class HomeFavoriteCell: UITableViewCell
@IBOutlet weak var imglLocation: UIImageView!
override func awakeFromNib()
super.awakeFromNib()
// Initialization code
override func prepareForReuse()
//set your cell's state to default here
self.imglLocation.image = nil
【讨论】:
这会清除第一个和重复单元格的图像,有什么办法可以避免这种情况【参考方案4】:这是因为您正在使用
重复使用单元格tableView.dequeueReusableCellWithIdentifier("CompanyCell", forIndexPath: indexPath) as! CompanyCell
为避免这种情况,请重置cellForRowAtIndexPath
中的开关
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
// Configure the cell:
let cell = tableView.dequeueReusableCellWithIdentifier("CompanyCell", forIndexPath: indexPath) as! CompanyCell
cell.mySwitch.on = false // or Whatever your switch name is (from CompanyCell class)
cell.companyName.text = companies[indexPath.row]
return cell
或创建新的单元格,如
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
// Configure the cell:
let cell = CompanyCell()
cell.companyName.text = companies[indexPath.row]
return cell
【讨论】:
不要仅仅因为你有一个开关就停止使用dequeue
。这不是一个好主意。正如 rmaddy 所说,cellForRowAtIndexPath
应该设置开关,就像设置 companyName
一样。
为什么我会被否决,我只是给出了所有的选择
您被否决了,因为不建议您按照原始答案的建议关闭出队逻辑。您现在在此处合并的正确答案是保持出队逻辑,但只需设置开关。我建议完全放弃“创建新单元”的讨论,因为那是个坏主意。此外,仅将开关设置为 false
也是一个坏主意。您确实应该参考指示该开关状态的模型。
你们能帮我解决 cellForRowAtIndexPath 函数吗?抱歉,我只是在学习 swift。【参考方案5】:
在你的单元格中写func prepareForReuse()
class CompanyCell : UITableViewCell
@IBOutlet weak var companyName: UILabel!
@IBOutlet weak var companySwitch: UISwitch!
override func awakeFromNib()
super.awakeFromNib()
// Initialization code
override func prepareForReuse()
//set your cell's state to default here
self.companySwitch.isOn = false
【讨论】:
以上是关于如何快速修复 UITableCells 重复的主要内容,如果未能解决你的问题,请参考以下文章