gpt4 book ai didi

ios - FRC 更新后 TableViewController 不刷新

转载 作者:行者123 更新时间:2023-11-28 15:49:37 27 4
gpt4 key购买 nike

NSFetchedResultsController (FRC) 中选择一行时,我的应用程序允许通过转到详细信息 View Controller 来更改详细信息。保存更改后,编辑的行将返回并插入到 FRC 中。

.update代码在下面的switch中被触发:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .update:
configureCell(cell: tableView.cellForRow(at: indexPath! as IndexPath)!, indexPath: indexPath! as NSIndexPath)
tableView.reloadRows(at: [indexPath!], with: .automatic)
case .insert:
tableView.insertRows(at: [newIndexPath!], with: .automatic)
case .delete:
tableView.deleteRows(at: [indexPath!], with: .automatic)
case .move:
tableView.moveRow(at: indexPath! as IndexPath, to: newIndexPath! as IndexPath)
}
}

configureCell() 方法是:

func configureCell(cell: UITableViewCell, indexPath: NSIndexPath) {
var handicap: Float

let cellIdentifier = "PlayerTableViewCell"

guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath as IndexPath) as? PlayerTableViewCell else {
fatalError("The dequeued cell is not an instance of PlayerTableViewCell")
}

// Populate cell from the NSManagedObject instance
guard let player = fetchedResultsController.object(at: indexPath as IndexPath) as? Golfer else {
fatalError("Unexpected Object in FetchedResultsController")
}

let firstName = player.value(forKey: "firstName") as! String?
let lastName = player.value(forKey: "lastName") as! String?
let fullName = firstName! + " " + lastName!
handicap = player.value(forKey: "exactHandicap") as! Float

cell.playerFullName?.text = fullName

cell.playerPhoto.image = UIImage(data: player.value(forKey: "photo") as! Data)

cell.numExactHandicap.text = "\(Int(handicap))"
cell.numStrokesReceived.text = "\(handicap.cleanValue)"

print("Object for configuration: \(player)")
}

细胞类定义是:

class PlayerTableViewCell: UITableViewCell {

//MARK: Properties
@IBOutlet weak var playerFullName: UILabel!
@IBOutlet weak var playerPhoto: UIImageView!
@IBOutlet weak var exactHandicapLabel: UILabel!
@IBOutlet weak var strokesReceivedLabel: UILabel!
@IBOutlet weak var numExactHandicap: UILabel!
@IBOutlet weak var numStrokesReceived: 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
}

-- 编辑 #1 --

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

// Table view cells are reused and should be dequeued using a cell identifier
let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerTableViewCell", for: indexPath)

configureCell(cell: cell, indexPath: indexPath as NSIndexPath)

return cell
}

我得到的行为在很多方面都是出乎意料的。

  1. 屏幕上的数据不会随着 .update 代码的处理而更新,保留 FRC 中预先编辑的值。

  2. 只有当我选择表格中的同一行时,该行才会刷新。 IE。它显示旧值,但在我再次选择该行时更改为新值,然后再次启动已编辑的行。

  3. 当我选择除第 0 行以外的任何行时,它第一次将单元格中的所有值设置为 Storyboard中显示的默认值。但是,在任何情况下,第 0 行从不在 segue 之前更改。

非常欢迎任何见解!

-- 编辑#3 [2017 年 4 月 20 日]--

一段时间以来,我一直在努力解决这个问题。核心问题仍然存在 - 屏幕上的数据不会在 .update 代码处理后刷新,保留 FRC 中的预编辑值。

关键代码段现在看起来像这样:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .update:
golferView.reloadRows(at: [indexPath!], with: .automatic)
case .insert:
golferView.insertRows(at: [newIndexPath!], with: .automatic)
case .delete:
golferView.deleteRows(at: [indexPath!], with: .automatic)
case .move:
golferView.moveRow(at: indexPath! as IndexPath, to: newIndexPath! as IndexPath)
}
}

func configureCell(cell: UITableViewCell, indexPath: NSIndexPath) {
var handicap: Float
var player: Golfer

let cellIdentifier = "PlayerTableViewCell"

guard let cell = golferView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath as IndexPath) as? PlayerTableViewCell else {
fatalError("The dequeued cell is not an instance of PlayerTableViewCell")
}

// Populate cell from the NSManagedObject instance
player = fetchedResultsController.object(at: indexPath as IndexPath)

let firstName = player.value(forKey: "firstName") as! String?
let lastName = player.value(forKey: "lastName") as! String?
let fullName = firstName! + " " + lastName!
handicap = player.value(forKey: "exactHandicap") as! Float

cell.playerFullName?.text = fullName

cell.playerPhoto.image = UIImage(data: player.value(forKey: "photo") as! Data)

cell.numExactHandicap.text = "\(Int(handicap))"
cell.numStrokesReceived.text = "\(handicap.cleanValue)"

print("Object for configuration: \(player). And cell values are = \(String(describing: cell.playerFullName?.text)), \(String(describing: cell.numExactHandicap.text)), \(String(describing: cell.numStrokesReceived.text))")
}

我已验证 controller() 方法正确触发并且 .update 开关触发 reloadRows。这反过来会触发 configureCell(),其中从 FRC 返回的行的内容是正确的,并且插入到单元格中的值与从 FRC 返回的匹配。它只是不会刷新 UI。

最佳答案

在调查内存使用问题时,我偶然发现了对 dequeueReusableCell 的重复调用,修复后解决了我一直遇到的问题。

在我的文章中,dequeueReusableCellconfigureCell 中被调用。在 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 调用中调用 configureCell 之前也会调用它。

我现在回到正轨了!

关于ios - FRC 更新后 TableViewController 不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42493438/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com