TableView section update depend on CoreData transient property change

半腔热情 提交于 2019-12-24 03:28:14

问题


I'm trying to develop a timetable app.

I have TableViewController which shows the classes on current day. In viewDidLoad( ) I fetch the classes with NSFetchedResultsController:

let fetchRequest = NSFetchRequest(entityName: "Lessons")
let predicate = NSPredicate(format: "startsday = '\(dateFormatter.stringFromDate(NSDate()))'", NSDate())
fetchRequest.predicate = predicate
let sortDescriptorStarts = NSSortDescriptor(key: "starts", ascending: true)
let sortDescriptorTitle = NSSortDescriptor(key: "title", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptorStarts, sortDescriptorTitle]
fetchRequest.fetchBatchSize = 30
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: "sectionIdentifier", cacheName: nil)
fetchedResultsController.delegate = self
fetchedResultsController.performFetch(nil)

And when I set sectionNameKeyPath: "sectionIdentifier"(which is a transient property) they are sorted into three groups "Past", "Now", "Next" depend on current time. It is working. I have a screenshot here.

My problem is: As time goes by the sections aren't updated
The rows should move out and move in other sections and eventually they should all go into the "Past" section, and the "Now", "Next" sections should be deleted.

I can update the sectionIdentifier transient property, but my fetchedResultController doesn't want to notice the changes...

I don't want to use tableView.reloadData( ) because i want animations.

(There is a similar question, but the end of it is different. I can't get my answer.)

Thanks!


回答1:


I have found a solution for this problem. It is definitely not the best but it's working nicely. (Swift 2.3)

First, I have a transient property called "sectionIdentifier".This could be "NOW", "NEXT" and "PAST" depend on the current time.I added a new persistent property next to this transient called "sectionID". This property's purpose is to tell if the lesson status (NOW, NEXT, PAST) changed. I changed my original fetch to this:

let fetchRequest = NSFetchRequest(entityName: "Lessons")
let predicate = NSPredicate(format: "startsday = '\(dateFormatter.stringFromDate(NSDate()))'", NSDate())
fetchRequest.predicate = predicate
let sortDescriptorStarts = NSSortDescriptor(key: "starts", ascending: true)
let sortDescriptorTitle = NSSortDescriptor(key: "title", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptorStarts, sortDescriptorTitle]
fetchRequest.fetchBatchSize = 30
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: "sectionIdentifier", cacheName: nil)
fetchedResultsController.delegate = self
do {
    try fetchedResultsController.performFetch()
} catch _ {
   //Handle error
}
if let lessons = fetchedResultsController.fetchedObjects as? [Lessons] {
    for lesson in lessons {
        if lesson.sectionID != lesson.sectionIdentifier! {
            lesson.setValue(lesson.sectionIdentifier!, forKey: "sectionID")
            moc.refreshObject(lesson, mergeChanges: true)
        }
    }
}

After the fetch I set this persistent property to the transient's value. (last 8 line above)

In viewDidLoad() I added this line.

timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(TodayViewController.update), userInfo: nil, repeats: true)

I update my transient property every second. My update method looks like this:

func update() {
    for lesson in fetchedResultsController.fetchedObjects as! [Lessons] {
        if lesson.sectionID != lesson.sectionIdentifier! {
            lesson.setValue(lesson.sectionIdentifier!, forKey: "sectionID")
            moc.refreshObject(lesson, mergeChanges: true)
            do {
                try moc.save()
            }
            catch _ {
                //Handle error
            }
        }
    }
}

So my transient property will always give the lessons current status and the persistent one will alway give the tableviewcell's status. If there is difference I put my transient value into the persistent property and with moc.refreshobject() i will get a the proper FetchedResultControllerDelegate method and i can handle the tableview changes there.



来源:https://stackoverflow.com/questions/32028318/tableview-section-update-depend-on-coredata-transient-property-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!