首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在使用Swift领域Results<>或List<>实例时避免延迟或调整coordinator.drop的计时?

如何在使用Swift领域Results<>或List<>实例时避免延迟或调整coordinator.drop的计时?
EN

Stack Overflow用户
提问于 2019-06-29 09:26:33
回答 1查看 298关注 0票数 0

在学习iOS开发的同时,我正在使用Realm Swift构建一个待办事项列表。当我尝试使用coordinator.drop(item.dragItem, toItemAt: destinationIndexPath)对商品进行重新排序时,我的collectionView遇到了问题。

当我包含coordinator时,被拖放的项目首先显示最初位于该索引处的单元格的内容,然后在一段延迟之后被所拖动的单元格的内容所取代。如果我没有包括协调器,那么拖放就会正常工作,并且项目在拖放时会正确地交换(但动画是一个单元格向下缩小到中心并有一点刺耳的动画)。

当我在collectionView中重新排序项目时:

代码语言:javascript
复制
func reorderItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView) {
        if let item = coordinator.items.first,
            let sourceIndexPath = item.sourceIndexPath {
                do {
                    try self.realm.write {
                          // standard category is of type Category
                          // items is of type List<Task>
                          standardCategory?.items.remove(at: sourceIndexPath.item)
                          standardCategory?.items.insert(item.dragItem.localObject as! Task, at: destinationIndexPath.item)
                    }
                } catch {
                    print("error reording new items, \(error)")
                }
            coordinator.drop(item.dragItem, toItemAt: destinationIndexPath)
        }
    }

在viewDidLoad()中处理collectionView的更新:

代码语言:javascript
复制
 self.notificationToken = tasks!.observe {
            (changes: RealmCollectionChange) in
            switch changes {
            case .initial(_):
                self.collectionView.reloadData()
            case .update(_, let deletions, let insertions, let modifications):
                 self.collectionView.performBatchUpdates({
                    self.collectionView.deleteItems(at: deletions.map({ IndexPath(item: $0, section: 0) }))
                    self.collectionView.insertItems(at: insertions.map({ IndexPath(item: $0, section: 0) }))
                    self.collectionView.reloadItems(at: modifications.map({ IndexPath(item: $0, section: 0) }))
                 }, completion: { status in
                    self.collectionView.reloadData()
                 })
            case .error(_):
                print("error")
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-29 16:13:13

我想我现在可以正常工作了。假设边缘情况不会破坏它,下面是答案:

我需要在tasks.observe之外处理模型更新和collectionView更新,以便更准确地控制事件的顺序。您可以使用try realm.commitWrite(withoutNotifying: [notificationToken!])来实现这一点

我认为关键是重新排序删除和更新项的顺序: 1.从模型中删除2.从集合视图中删除3.插入到模型4.使用协调器删除项5.插入到集合视图6.重新加载部分(可选,我认为UI更改需要它)

代码语言:javascript
复制
func reorderItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView) {
        if let item = coordinator.items.first {
            if let localObject = item.dragItem.localObject as? Task {
                if let sourceIndexPath = item.sourceIndexPath {
                    do {
                        try self.realm.write {
                            standardCategory?.items.remove(at: sourceIndexPath.item)
                            try realm.commitWrite(withoutNotifying: [notificationToken!])
                        }
                    } catch { print("error reording new items, \(error)") }
                    collectionView.deleteItems(at: [sourceIndexPath])
                }
                do {
                    try self.realm.write {
                        standardCategory?.items.insert(localObject, at: destinationIndexPath.item)
                        try realm.commitWrite(withoutNotifying: [notificationToken!])
                    }
                } catch { print("error reording new items, \(error)") }

                self.collectionView.performBatchUpdates({
                    coordinator.drop(item.dragItem, toItemAt: destinationIndexPath)
                    collectionView.insertItems(at: [destinationIndexPath])
                }, completion: { status in
                    let indexSet = IndexSet(integer: destinationIndexPath.section)
                    collectionView.reloadSections(indexSet)
                })
            }
        }
    }

解决方案:事实证明,在使用拖放进行排序时不能使用结果(不是100%确定原因,但知道这一点会很好)。以下是使用List的当前工作解决方案:

代码语言:javascript
复制
func reorderItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView) {
        if let item = coordinator.items.first {
            if let localObject = item.dragItem.localObject as? Task {
                if let sourceIndexPath = item.sourceIndexPath {
                    self.collectionView.performBatchUpdates({
                        do {
                            standardCategory!.realm!.beginWrite()

                            standardCategory!.items.remove(at: sourceIndexPath.item)
                            collectionView.deleteItems(at: [sourceIndexPath])

                            self.standardCategory!.items.insert(localObject as Task, at: destinationIndexPath.item)

                            coordinator.drop(item.dragItem, toItemAt: destinationIndexPath)

                            collectionView.insertItems(at: [destinationIndexPath])
                            try standardCategory!.realm!.commitWrite(withoutNotifying: [notificationToken!])

                        } catch { print("error reording new items, \(error)") }
                    }, completion: nil)
                }
            }
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56814490

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档