7

WWDC 2019真的充满了 iOS 的新东西和新的TableViews数据CollectionViewUITableViewDiffableDataSource

我已经成功地将上述新数据源与核心数据集成,删除和插入新记录没有任何问题,不幸的是我在将项目从一个部分移动到另一个部分时遇到问题,如果我试图将最后一个单元格移动到另一个单元格中,就会出现问题这部分 。

下面是我的代码:

表视图设置

private func setupTableView() {
       diffableDataSource = UITableViewDiffableDataSource<Int, Reminder>(tableView: remindersTableView) { (tableView, indexPath, reminder) -> UITableViewCell? in
           let cell = tableView.dequeueReusableCell(withIdentifier: "SYReminderCompactCell", for: indexPath) as! SYReminderCompactCell
        var reminderDateString = ""
        let reminderTitle = "\(reminder.emoji ?? "") \(reminder.title  ?? "")"

        if let date = reminder.date {// check if reminder has date or no , if yes check number of todos and if date in today
            let dateFormatter = SYDateFormatterManager.sharedManager.getDateFormaatter()
            dateFormatter.dateStyle = .none
            dateFormatter.timeStyle = .short
            reminderDateString = dateFormatter.string(from: date)
        }

            let toDosList = SYCoreDataManager.sharedManager.fetchAllToDosToOneReminder(reminder: reminder)
                 cell.indexPath = indexPath
                 cell.showMoreDelegate = self
                 cell.initializeToDosCompactView(toDoList: toDosList ?? [],reminderTitleText: reminderTitle,reminderDateText: reminderDateString)
                 cell.changeTextViewStyle(isChecked: reminder.isCompleted)

           return cell
       }

    setupSnapshot(animated: true)
   }

NSDiffableDataSourceSnapshot用表视图数据创建一个

private func setupSnapshot(animated: Bool) {
    diffableDataSourceSnapshot = NSDiffableDataSourceSnapshot<Int, Reminder>()

    for (i , section) in (fetchedResultsController.sections?.enumerated())! {
        diffableDataSourceSnapshot.appendSections([i])
        let items = section.objects
        diffableDataSourceSnapshot.appendItems(items as! [Reminder])
        diffableDataSource?.apply(self.diffableDataSourceSnapshot, animatingDifferences: animated, completion: nil)
    }

}

NSFetchedResultsControllerDelegate对于部分和行

     func controller(_ controller: 
    NSFetchedResultsController<NSFetchRequestResult>, didChange 
    anObject: Any, at indexPath: IndexPath?, for type: 
    NSFetchedResultsChangeType, 
   newIndexPath: IndexPath?) {

    switch type {
    case .insert:
        if let indexPath = newIndexPath {
            let section = fetchedResultsController.sections![indexPath.section]
            self.diffableDataSourceSnapshot.appendItems(section.objects as! [Reminder], toSection: indexPath.section)
            self.diffableDataSource?.apply(self.diffableDataSourceSnapshot, animatingDifferences: true)

        }
        break
    case .update:
        break
    case .delete:

        if let indexPath = indexPath {
            guard let item = self.diffableDataSource?.itemIdentifier(for: indexPath) else { return }
            self.diffableDataSourceSnapshot.deleteItems([item])
            self.diffableDataSource?.apply(self.diffableDataSourceSnapshot, animatingDifferences: true)
        }
        break
    case .move:
        if let indexPath = indexPath {
            guard let item = self.diffableDataSource?.itemIdentifier(for: indexPath) else { return }
            self.diffableDataSourceSnapshot.appendSections([indexPath.section])
            self.diffableDataSourceSnapshot.deleteItems([item])
            self.diffableDataSource?.apply(self.diffableDataSourceSnapshot, animatingDifferences: true)
        }
        if let newIndexPath = newIndexPath {
            let section = fetchedResultsController.sections![newIndexPath.section]

            // let items = fetchedResultsController.object(at: indexPath)
            print("snapppp" , diffableDataSourceSnapshot.sectionIdentifiers)
            let items = section.objects as! [Reminder]

            self.diffableDataSourceSnapshot.appendItems(items, toSection: newIndexPath.section)
            self.diffableDataSource?.apply(self.diffableDataSourceSnapshot, animatingDifferences: true)
        }
        break
    }
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
    switch type {
    case .insert:
        setupSnapshot(animated: false)
        break
    case .update:
        break
    case .delete:
        let section = self.diffableDataSourceSnapshot.sectionIdentifiers[sectionIndex]
        self.diffableDataSourceSnapshot.deleteSections([section])
                self.diffableDataSource?.apply(self.diffableDataSourceSnapshot, animatingDifferences: true)
        //setupSnapshot(animated: false)

        break
    case .move:
        break
    }
}
4

1 回答 1

11
  • 要顺利使用 Core Data,必须将数据源声明为

    UITableViewDiffableDataSource<String,NSManagedObjectID>
    
  • setupTableView重命名闭包参数标签

    (tableView, indexPath, objectID) -> UITableViewCell? in
    

    并得到提醒

    let reminder = self.fetchedResultsController.object(at: indexPath)
    

    或者

    let reminder = try! self.managedObjectContext.existingObject(with: objectID) as! Reminder
    
  • 然后替换整个方法

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, 
         didChange anObject: Any, 
         at indexPath: IndexPath?, 
         for type: NSFetchedResultsChangeType, 
         newIndexPath: IndexPath?) { ... }
    

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, 
         didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, 
         for type: NSFetchedResultsChangeType) { ... }
    

    只是与

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {       
        self.diffableDataSource.apply(snapshot as NSDiffableDataSourceSnapshot<String, NSManagedObjectID>, animatingDifferences: true)
    }
    
  • 也删除方法setupSnapshot,不需要。在调用performFetch托管对象上下文中的任何更改后,框架会正确创建快照并调用委托方法。

于 2020-01-07T12:32:29.577 回答