2017-02-27 24 views
0

NSFetchedResultsController(FRC)の行を選択するとき、私のアプリケーションでは、詳細ビューコントローラに分割することによって詳細を変更することができます。変更を保存した後、編集された行が返され、FRCに挿入されます。FRCが更新された後にTableViewControllerが更新されない

.updateコードは以下switchにトリガされる:

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)") 
} 

および細胞クラス定義は次のとおり:

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()方法がある

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 
    } 

}

- EDIT#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. オンスクリーンデータはFRCに事前編集した値を保持し、.updateコードの処理に続いて更新されません。

  2. テーブル内の同じ行を選択した場合にのみ、行が更新されます。私。古い値が表示されますが、瞬時に新しい値に変更されます。編集した行を再度起動する前に、行を再度選択します。

  3. 行0以外の行を初めて選択すると、セル内のすべての値がストーリーボードに表示されているデフォルト値に設定されます。ただし、ロー0 は決してに変更されます。

洞察力は大歓迎です!

- EDIT#3 [4月20」、2017] -

私はしばらくの間、この問題で離れてチッピングされてきました。中心的な問題が残っています - .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を更新するだけではありません。

+1

更新コードが呼ばれていますか?また、 'configureCell'と' reloadRows'の両方を呼び出す必要はありません。そして、「編集された行が返され、FRCに挿入された」ということはどういう意味ですか?新しい行が作成されていますか(更新ではありません)? –

+0

こんにちは。順序: 1.はい、 '.update'コードが呼び出されています。私がそこにブレークポイントを設定すると、それが止まり、私はステップインすることができます。 2. 'reloadRows'の呼び出しをコメントアウトすると、動作が変わります。あらかじめ編集された元の行の内容を表示するのではなく、行の内容をデフォルトのストーリーボードの値にリセットします。 'reloadRows'を呼び出すと、私が必要とする更新された値ではなく、古い行がテーブルに取り込まれます。 3.私は、編集した詳細をFRCの元の行への更新として反映させたいということです。 – Dave

+0

2. 'configureCell'メソッド呼び出しを削除する必要があるということは、その行をリロードして自動的に呼び出されるためです。 –

答えて

1

メモリ使用量の問題を調査している間に、私はdequeueReusableCellへの重複呼び出しを見つけました。これは、修正されたときに私が抱えていた問題を解決しました。

私のポストでは、dequeueReusableCellconfigureCellと呼ばれています。 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCellコールでconfigureCellを呼び出す直前にも呼び出されます。

私は今戻っています!

関連する問題