Ios Swift:cellForRowAtIndexPath中出现意外结果

Ios Swift:cellForRowAtIndexPath中出现意外结果,ios,swift,uitableview,Ios,Swift,Uitableview,我有一个自定义的UITableView,单元格是分区的,而不是行的,总共有5个单元格。每个单元格都有一个按钮,我希望第五个单元格按钮(tableButton)与其余单元格有不同的标题 这一切都与我下面的代码配合得很好,最初的4个单元格根据代码具有正确的标题。但是,当我向下滚动第5个单元格(具有预期标题),然后向上滚动到第一个单元格时,第一个单元格现在已更改为第五个单元格的特定标题 import UIKit class TableViewController: UIViewController,

我有一个自定义的UITableView,单元格是分区的,而不是行的,总共有5个单元格。每个单元格都有一个按钮,我希望第五个单元格按钮(tableButton)与其余单元格有不同的标题

这一切都与我下面的代码配合得很好,最初的4个单元格根据代码具有正确的标题。但是,当我向下滚动第5个单元格(具有预期标题),然后向上滚动到第一个单元格时,第一个单元格现在已更改为第五个单元格的特定标题

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
委托方法中设置单元格的内容。很抱歉回复得太晚,生活介于两者之间;)