我有一个UITableViewController和一个普通的ViewController . 在VC(名为nyTankning)中,用户将键入保存到Core Data数据库的信息 . 数据库被加载并显示在UITableVieController中 .
现在我希望能够编辑保存在数据库中的信息 . 我已经找到了答案,但我还没有找到任何有用的东西,因为我在使用了以下retrieving core data into tableview cells swift后使用了NSFetchedResultsController
现在我在TableViewController中编写的代码如下所示:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if segue.identifier == "update" {
let indexPath = self.tableView.indexPathForSelectedRow()
let selectedCell = fetchedResultsController?.indexPathForObject(indexPath!) as? NSManagedObject
let nyTankning: nyTankningViewController = segue.destinationViewController as nyTankningViewController
nyTankning.liter = selectedCell?.valueForKey("liter") as String
nyTankning.kronor = selectedCell?.valueForKey("kronor") as String
nyTankning.exisitingTankning = selectedCell
}
但是我从调试器中了解到indexPath没有正确编写 .
2015-01-16 17:14:22.207 TankApp [4232:241135] ***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [NSIndexPath objectID]:无法识别的选择器发送到实例0x7c274660'
编辑:这是整个UITableViewController的完整代码:
import Foundation
import UIKit
import CoreData
class tankningarTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var firstTime = 0
let managedObjectContext: NSManagedObjectContext? = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext
var fetchedResultsController: NSFetchedResultsController?
override func viewDidLoad() {
super.viewDidLoad()
fetchedResultsController = NSFetchedResultsController(fetchRequest: allaTankningarFetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController?.delegate = self
fetchedResultsController?.performFetch(nil)
}
func alertViewFirstTime() {
let alertController = UIAlertController(title: "TankApp", message:
"Du kan lägga till en ny tankning genom att trycka på plusknappen (+).", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
func allaTankningarFetchRequest() -> NSFetchRequest {
var fetchRequest = NSFetchRequest(entityName: "Tankningslista")
let sortDescriptor = NSSortDescriptor(key: "datum", ascending: false)
fetchRequest.predicate = nil
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchBatchSize = 20
return fetchRequest
}
override func viewDidAppear(animated: Bool) {
if firstTime == 0 {
alertViewFirstTime()
firstTime++
}
else {
return
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return fetchedResultsController?.sections?[section].numberOfObjects ?? 0
}
//MARK: NSFetchedResultsController Delegate Functions
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case NSFetchedResultsChangeType.Insert:
tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Delete:
tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Move:
break
case NSFetchedResultsChangeType.Update:
break
default:
break
}
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
}
switch editingStyle {
case .Delete:
managedObjectContext?.deleteObject(fetchedResultsController?.objectAtIndexPath(indexPath) as Model)
managedObjectContext?.save(nil)
case .Insert:
break
case .None:
break
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case NSFetchedResultsChangeType.Insert:
tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Delete:
tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Move:
tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!), withRowAnimation: UITableViewRowAnimation.Fade)
tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Update:
tableView.cellForRowAtIndexPath(indexPath!)
break
default:
break
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Configure the cell...
let CellID: NSString = "Cell"
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(CellID) as UITableViewCell
let fetchRequest = NSFetchRequest(entityName: "Tankningslista")
if let cellContact = fetchedResultsController?.objectAtIndexPath(indexPath) as? Model {
cell.textLabel?.text = "\(cellContact.datum)"
cell.detailTextLabel?.text = "\(cellContact.liter) Liter, \(cellContact.kronor) Kronor, \(cellContact.literpris) Kronor/Liter"
}
return cell
}
/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the item to be re-orderable.
return true
}
*/
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "update" {
let destination = segue.destinationViewController as nyTankningViewController
let indexPath = self.tableView.indexPathForCell(sender as Model)
destination.event = indexPath != nil ? fetchedResultsController.objectAtIndexPath(indexPath!) as? NSManagedObject : nil
}
}
}
1 回答
我使用三元运算符来处理打开可选索引路径的情况,但是
if let
也能正常工作以避免因此而发生的任何崩溃 . 另外,我建议使用indexPathForCell
并使用sender
作为您的单元而不是indexPathForSelectedRow
.使用此方法,您将整个托管对象传递到下一个视图控制器,您可以在其中相应地处理它 . 如果要维护此方法中的所有目标类变量的设置,可以使用
if let
来打开可选的索引路径,如下所示:See a sample GitHub project here.