简体   繁体   English

如何按修改日期对核心数据对象进行排序并在 tableView 中以正确的顺序列出?

[英]How do I sort core data objects by date modified and list it in the right order in a tableView?

I have been struggling a long time with moving cells in a tableView and getting them in the correct order.我一直在努力在tableView中移动cells并以正确的顺序排列它们。 I want to be able to drag the cells from one place to another using rx.itemMoved .我希望能够使用rx.itemMovedcells从一个地方拖到另一个地方。 The order also has to persist over time so I save it to coreData and then sort it according to Date as suggested here:该订单还必须随着时间的推移而持续存在,因此我将其保存到coreData ,然后按照此处建议的Date对其进行sort

Is there a way to keep the sorting in core data in the time order the objects are added? 有没有办法按照添加对象的时间顺序对核心数据进行排序?

But I just can't seem to get it right with the sorting.但我似乎无法正确排序。 I don't think I fully understand how to sort it based on date.我认为我不完全了解如何根据日期对其进行排序。

I mock data like this:我模拟这样的数据:

func mockData() {
    let entity = NSEntityDescription.entity(forEntityName: "LocalDoorCoreDataObject", in: context)
    var data: [LocalDoorCoreDataObject] = []
    for i in 1...3 {
        let myEntity = LocalDoorCoreDataObject(entity: entity!, insertInto: context)
        myEntity.dCount = Int16(i)
        myEntity.dName = "M \(i)"
        data.append(myEntity)
    }
    viewModel.mockedRelay.accept(data.compactMap{ RemoteTableViewCellViewModel(localDoor: $0)})
}

And this triggers the bind on my tableView :这会触发我的tableView上的bind

func setBindings() {
    viewModel.mockedRelay.bind(to: tableView.rx.items(cellIdentifier: RemoteTableViewCell.identifier, cellType: RemoteTableViewCell.self)) { row, data, cell in
        cell.viewModel = data
    }.disposed(by: disposeBag)
}

Now when I drag a cell from one place to another:现在,当我将一个cell从一个地方拖到另一个地方时:

tableView.rx.itemMoved.subscribe(onNext: { [weak self] indexPaths in
    let delete = self?.viewModel.mockedRelay.value[indexPaths.sourceIndex.row]
    self?.deleteOne(position: indexPaths.sourceIndex.row) //deletes object in core data 

    self?.setData2(data: delete!) //add the moved object to cd. A new date is added to it
    self?.completionRelay?.accept("DATA SAVED") //Saves data for core data
}).disposed(by: disposeBag)

When I add a new object to coreData a new date is set:当我将新的 object 添加到coreData时,会设置一个新日期:

extension LocalDoorCoreDataObject {
    public override func awakeFromInsert() {
        setPrimitiveValue(Date(), forKey: "dModifiedDate")
    }
}

Now, the thing I don't get is how date should help me sort it in the way I left it when leaving the view .现在,我不明白date应该如何帮助我按照离开view时的方式对其进行排序。 If I have three cells and move one of them, the moved cell gets a higher date and the other two have lower dates .如果我有三个cells并移动其中一个,则移动的cell会获得更高的date ,而另外两个则拥有更低的dates What if I left the moved cell in the middle?如果我将移动的cell留在中间怎么办? Then how would its higher date help me at all?那么它的更高日期将如何帮助我呢? Here's the fetch code:这是fetch代码:

func fetchMyData2() {
        let request = NSFetchRequest<LocalDoorCoreDataObject>(entityName: "LocalDoorCoreDataObject")
        do {
            Observable.of(try context?.fetch(request))
                .map { item in
                    item?.sorted(by: {(item1, item2) -> Bool in
                        let ordered = item1.dModifiedDate?.compare(item2.dModifiedDate!) == .orderedAscending
                        return ordered
                    })
                }
                .subscribe(onNext: { value in
                    self.viewModel.mockedRelay.accept(value!.compactMap {
                        return RemoteTableViewCellViewModel(localDoor: $0)})
                })
                .disposed(by: disposeBag)

        } catch {
            print("🙊error", error.localizedDescription) }
    }

Let me know if there is something I haven't explained clearly enough or if there is additional code I need to post.如果有什么我解释得不够清楚,或者我需要发布其他代码,请告诉我。 I'm aware that a lot of this is bad code, but I really just want to get it to work for now.我知道其中很多都是糟糕的代码,但我真的只想让它现在工作。

Ok, I solved it by doing this:好的,我通过这样做解决了它:

var items = self.mockedRelay.value
let item = items.remove(at: indexPaths.sourceIndex.row)
items.insert(item, at: indexPaths.destinationIndex.row)

Now that the array is sorted the way I want it I can add index values to it:现在array按我想要的方式排序,我可以向它添加索引值:

for (index, item) in items.enumerated() {
    item.localDoor.dRow = Int16(index)
}

And that's it!就是这样! New index values for all objects every time the cells are moved.每次移动cells时,所有objects的新索引值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM