Ios Swift:cellForRowAtIndexPath中出现意外结果
我有一个自定义的UITableView,单元格是分区的,而不是行的,总共有5个单元格。每个单元格都有一个按钮,我希望第五个单元格按钮(tableButton)与其余单元格有不同的标题 这一切都与我下面的代码配合得很好,最初的4个单元格根据代码具有正确的标题。但是,当我向下滚动第5个单元格(具有预期标题),然后向上滚动到第一个单元格时,第一个单元格现在已更改为第五个单元格的特定标题Ios Swift:cellForRowAtIndexPath中出现意外结果,ios,swift,uitableview,Ios,Swift,Uitableview,我有一个自定义的UITableView,单元格是分区的,而不是行的,总共有5个单元格。每个单元格都有一个按钮,我希望第五个单元格按钮(tableButton)与其余单元格有不同的标题 这一切都与我下面的代码配合得很好,最初的4个单元格根据代码具有正确的标题。但是,当我向下滚动第5个单元格(具有预期标题),然后向上滚动到第一个单元格时,第一个单元格现在已更改为第五个单元格的特定标题 import UIKit class TableViewController: UIViewController,
import UIKit
class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 5
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.gray.cgColor
cell.tableButton.tag = indexPath.section
if indexPath.section == 4 {
cell.tableTitle.isHidden = true
cell.tableButton.setTitle("Special", for: .normal)
} else {
cell.tableButton.setTitle("Normal", for: .normal)
}
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: 15))
returnedView.backgroundColor = UIColor.groupTableViewBackground
return returnedView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 15
}
}
我在if cell.tableButton.tag==4条件中添加了一个print语句,每次向下滚动到第五个单元格时,它都会被打印出来
import UIKit
class TableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 5
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.gray.cgColor
cell.tableButton.tag = indexPath.section
if indexPath.section == 4 {
cell.tableTitle.isHidden = true
cell.tableButton.setTitle("Special", for: .normal)
} else {
cell.tableButton.setTitle("Normal", for: .normal)
}
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: 15))
returnedView.backgroundColor = UIColor.groupTableViewBackground
return returnedView
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 15
}
}
CustomCell.swift:
import UIKit
class CustomCell: UITableViewCell {
@IBOutlet weak var tableButton: UIButton!
@IBOutlet weak var tableTitle: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
if indexPath.section == 4 {
cell.tableButton.setTitle("Special", for: .normal)
} else {
cell.tableButton.setTitle("Normal", for: .normal)
}
return cell
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 250
}
}
import UIKit
class CustomCell: UITableViewCell {
@IBOutlet weak var tableButton: UIButton!
override func prepareForReuse() {
tableButton.setTitle("RESET", for: .normal)
}
}
我想这是因为您使用的是
dequeReusableCell
方法。由于tableview中只有5个单元格,我认为如果您不再对单元格进行消隐,而是每次都创建一个新的单元格实例,这不会对您造成任何伤害。这不是一个最佳实践,但却是一个简单的解决方案 我已经重新创建了您的场景,但我没有问题让它正常工作。我想这可能与您的CustomCell
中的某些内容有关
ViewController.swift:
import UIKit
class CustomCell: UITableViewCell {
@IBOutlet weak var tableButton: UIButton!
@IBOutlet weak var tableTitle: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
if indexPath.section == 4 {
cell.tableButton.setTitle("Special", for: .normal)
} else {
cell.tableButton.setTitle("Normal", for: .normal)
}
return cell
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 250
}
}
import UIKit
class CustomCell: UITableViewCell {
@IBOutlet weak var tableButton: UIButton!
override func prepareForReuse() {
tableButton.setTitle("RESET", for: .normal)
}
}
CustomCell.swift:
import UIKit
class CustomCell: UITableViewCell {
@IBOutlet weak var tableButton: UIButton!
@IBOutlet weak var tableTitle: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
if indexPath.section == 4 {
cell.tableButton.setTitle("Special", for: .normal)
} else {
cell.tableButton.setTitle("Normal", for: .normal)
}
return cell
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 250
}
}
import UIKit
class CustomCell: UITableViewCell {
@IBOutlet weak var tableButton: UIButton!
override func prepareForReuse() {
tableButton.setTitle("RESET", for: .normal)
}
}
当然,这是一个简化的UITableView实现,但是在示例中添加更多的代码,也许其他人可以看到或重新创建您的问题。这看起来像是一个单元重用问题,因为您使用的是
tableView.dequeueReusableCell(带有标识符:“cell”,用于:indexPath)
这里有几种解决方案。第一种方法是不重用并创建一个新的,但这会导致性能下降,因为会使用更多内存
更好的解决方案是准备在tableViewCell中重用。您应该覆盖自定义tableViewCell中的方法
prepareforeuse
。在该方法中,将视图设置为其初始状态(文本、字母等)。请记住先调用super.preparefore。可能单元格的状态已更改。将.normal
替换为[]
对于所有情况,我们有5个部分,每个部分有5个单元?5个部分,每个部分有1个单元,总共5个单元。这是因为第5个单元被重用,因为这一行dequeueReusableCell
代替了第1个单元。penatheboss,我刚刚尝试过这样做,如果indexath.section==4,则在单元格中隐藏一个标签。当我向上滚动时,第一个单元格标题也会消失,因此单元格的状态不会导致问题。这不是一个好方法…因为它会累积内存使用量。他也可以使用prepareforeuse
方法,但由于他的tableview中的单元格数是静态的,只有5个单元格,我认为这会更容易在不造成太大伤害的情况下为他提供解决方案。他不应使用prepareforeuse
设置单元格内容。该委托方法并不适用于此。在重用单元格时,tableView(uquo:cellForRowAt:)
中的表视图委托应始终重置所有内容。使用prepareforeuse
是一种非常好的方法,但这是且不应该是使其工作的先决条件。UITableViewDelegate
应该调用CellForRowatineIndexPath
,这将依次获得单元格(新建或退出队列),并更改其上tableButton
的值。谢谢,此方法可用于重置按钮标题。如何将其用于按钮操作?如果我给“特殊”按钮一个不同于其他按钮的动作,那么第一个单元格实际上形成了正常和特殊动作。您如何设置按钮的动作??代码中不可见如果我添加了两个不同的操作(一个用于“特殊”按钮,另一个用于“正常”按钮,称为specialAction和normalAction),我如何使用prepareForResuse使单元格按其应有的方式运行,因为第一个单元格正在形成两个操作!别担心,我已经解决了我在PrepareForuse中从按钮上移除目标的问题!方法prepareforeuse
用于将单元格重置为适合重用的状态,而不是用于设置新数据。如果在最坏的情况下,您的单元格仍然不能正常工作,您可以在UITableView
中的willDisplayCell
委托方法中设置单元格的内容。很抱歉回复得太晚,生活介于两者之间;)