How to update user interface on Core Data?

假如想象 提交于 2020-01-14 06:03:40

问题


I have an app with UITableView, Core Data and NSFetchedResultsController as well. I have passed data to the DetailViewController. And I can delete them from the DetailViewController! In the Apple's iOS Notes app, you can see such as functions as I wanted! When you delete a notes from the DetailViewController ( for example ), object deleted and Notes app automaticlly shows the next or previos notes! I want to create such as function. How update user interface after deleted current object? Here's my codes! Thanks ` import UIKit import CoreData

class DetailViewController: UIViewController {

@IBOutlet weak var containerLabel: UILabel!

var retrieveData:NSManagedObject!
var managedObjectContext:NSManagedObjectContext!
var manager:Manager!

override func viewDidLoad() {
    super.viewDidLoad()
// Do any additional setup after loading the view.

    self.containerLabel.userInteractionEnabled = false
    self.containerLabel.textColor = UIColor.redColor()
    self.containerLabel.alpha = 0

    UIView.animateWithDuration(2.5) { () -> Void in
        self.containerLabel.alpha = 1
    }


    if let demo = self.retrieveData.valueForKey("titleField") as? String {
     self.containerLabel.text = demo
    }

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func backToMain(sender: AnyObject) {
    // Back to the MainTableViewController
    self.dismissViewControllerAnimated(true, completion: nil)
}
@IBAction func trashButton(sender: AnyObject) {

    self.managedObjectContext.deleteObject(retrieveData)

    do {
    try self.managedObjectContext.save()
    } catch {

    }
    self.dismissViewControllerAnimated(true, completion: nil)


}

`

If I have 5 items on the list like so:

When I select fourth item from the list ( for example ). And detailVC shows me selected item like this:

And I want to delete them. When I delete "Four" and then my containerLabel.text shows previous objects from the list. They're after "Four" is deleted, "Three","Two" and "One" as well. After "One" is deleted my containerLabel.text shows strings

But I have left single object called as "Five"

My problem is "Five"! I can't delete it. Example: In iOS Notes App, if you have five objects on the list like my demo app. When you select fourth object from the list ( for example ). And begin deleting them, after "Four" is delete iOS Notes App shows "Five". And "Five" ( last object on the list ) is deleted and then iOS Notes App shows "Three", "Two" and "One". Maybe problem line is here:

if index != 0 { self.retrieveData = fetchedObject[index! - 1] } else { self.retrieveData == fetchedObject[0] }


回答1:


Let's take the easy (but not so elegant) route here. You'll have to pass over all the fetched objects to the detail VC like this:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if segue.identifier == "yourSegueIdentifier"{

    if let destinationVC = segue.destinationViewController as? DetailViewController{

        destinationVC.managedObjectContext = yourContext
        destinationVC.retrieveData = yourManagedObject
        destinationVC.arrayOfFetchedObjects = yourFetchedResultsController.fetchedObjects
        //pass over other data...

        }
    }
}

Then, in your detailVC, write a method that will be executed when you press the delete button. Something like this:

@IBAction func trashButton(sender: AnyObject) {

//make sure you have an array with YourObjects
guard let fetchedObjects = arrayOfFetchedObjects as? [YourObjectType] else {return}

//get index of the shown object in the array of fetched objects
let indexOfObject = fetchedObjects.indexOf(retrieveData)

//delete the object from the context
self.managedObjectContext.deleteObject(retrieveData)

do {
    try self.managedObjectContext.save()

    //delete the object from the fetchedObjects array
    fetchedObjects.removeAtIndex(indexOfObject)
} catch {

}

//get the object that should be shown after the delete
if indexOfObject != 0{
    //we want the object that represents the 'older' note
    retrieveData = fetchedObjects[indexOfObject - 1]
    updateUserInterface(true)

}
else{
    //the index was 0, so the deleted object was the oldest. The object that is the oldest after the delete now takes index 0, so just use this index. Also check for an empty array.

    if fetchedObjects.isEmpty{ 
         updateUserInterface(false)
     }
    else{
        retrieveData = fetchedObjects[0]
        updateUserInterface(true)
    }

    }
}


func updateUserInterface(note: Bool){

switch note{

    case true:

        //update the user interface
        if let demo = retrieveData.valueForKey("titleField") as? String {
            self.containerLabel.text = demo
        }

    case false:

        self.containerLabel.text = "no more notes"

    }
}



回答2:


You either need to pass the details view controller

  1. A list of all managed objects and an index for where in the list to start
  2. A current managed object and a callback to get the next object

In order for it to have enough information to do what you want. The callback approach is nicest and is a simple form of delegate, where your master view controller is the delegate supplying the extra data.



来源:https://stackoverflow.com/questions/34984391/how-to-update-user-interface-on-core-data

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