Swift UITableView删除行项 - tableview数据源是Core Data [英] Swift UITableView delete row item - tableview datasource is Core Data

查看:723
本文介绍了Swift UITableView删除行项 - tableview数据源是Core Data的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经完成了我的第一个iOS应用程式,但是从正在从Core Data填充的表格视图中删除的问题。核心数据实体具有在单元中显示的4个属性。所有的例子我试图跟随使用一个归属实体。我也有两种类型的描述。不知道这是否对我的问题有任何影响。我的表视图正确填充..编辑选项可用,但一旦选择一行,删除触摸我得到一个错误,调试器停止在类AppDelegate:UIResponder,UIApplicationDelegate { and Xcode outputs the following

I've nearly finished my first iOS app but having a problem with deleting from a tableview that is being populated from Core Data. The core data entity has 4 attributes that are displayed in the cell. All example I have tried to follow use a single attributed entity. Also I have two sort descriptions. Not sure if this has any bearing on my problem. My tableview is populated correctly.. the edit option is available but once a row is selected and the delete touched I get an error, the debugger stops at the line class AppDelegate: UIResponder, UIApplicationDelegate { and Xcode outputs the following

    2016-04-25 20:00:05.739 MileageLogger[41673:17841244] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.60.7/UITableView.m:1716
2016-04-25 20:00:05.768 MileageLogger[41673:17841244] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (14) must be equal to the number of rows contained in that section before the update (14), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
*** First throw call stack:
(
    0   CoreFoundation                      0x00633494 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x02347e02 objc_exception_throw + 50
    2   CoreFoundation                      0x0063332a +[NSException raise:format:arguments:] + 138
    3   Foundation                          0x00a78322 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 118
    4   UIKit                               0x00f7b014 -[UITableView _endCellAnimationsWithContext:] + 17170
    5   UIKit                               0x00f94216 -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] + 363
    6   UIKit                               0x00f942a4 -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] + 56
    7   UIKit                               0x0fec584a -[UITableViewAccessibility deleteRowsAtIndexPaths:withRowAnimation:] + 65
    8   MileageLogger                       0x00062789 _TFC13MileageLogger30MileageLogsTableViewController9tableViewfTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 201
    9   MileageLogger                       0x00062827 _TToFC13MileageLogger30MileageLogsTableViewController9tableViewfTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 103
    10  UIKit                               0x00fafc94 -[UITableView animateDeletionOfRowWithCell:] + 185
    11  UIKit                               0x00f80ce5 __52-[UITableView _swipeActionButtonsForRowAtIndexPath:]_block_invoke + 110
    12  UIKit                               0x00fb17f3 -[UITableView _actionButton:pushedInCell:] + 178
    13  UIKit                               0x0121cc68 -[UITableViewCell _actionButtonPushed:] + 88
    14  libobjc.A.dylib                     0x0235c0b5 -[NSObject performSelector:withObject:withObject:] + 84
    15  UIKit                               0x00e23e38 -[UIApplication sendAction:to:from:forEvent:] + 118
    16  UIKit                               0x00e23db7 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64
    17  UIKit                               0x00fc7f3b -[UIControl sendAction:to:forEvent:] + 79
    18  UIKit                               0x00fc82d4 -[UIControl _sendActionsForEvents:withEvent:] + 433
    19  UIKit                               0x00fc72c1 -[UIControl touchesEnded:withEvent:] + 714
    20  UIKit                               0x013aad2e _UIGestureRecognizerUpdate + 12763
    21  UIKit                               0x00ea3efd -[UIWindow _sendGesturesForEvent:] + 1559
    22  UIKit                               0x00ea55b6 -[UIWindow sendEvent:] + 1137
    23  UIKit                               0x00e46be8 -[UIApplication sendEvent:] + 266
    24  UIKit                               0x0febc369 -[UIApplicationAccessibility sendEvent:] + 72
    25  UIKit                               0x00e1b769 _UIApplicationHandleEventQueue + 7795
    26  CoreFoundation                      0x00545e5f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    27  CoreFoundation                      0x0053baeb __CFRunLoopDoSources0 + 523
    28  CoreFoundation                      0x0053af08 __CFRunLoopRun + 1032
    29  CoreFoundation                      0x0053a846 CFRunLoopRunSpecific + 470
    30  CoreFoundation                      0x0053a65b CFRunLoopRunInMode + 123
    31  GraphicsServices                    0x04b2f664 GSEventRunModal + 192
    32  GraphicsServices                    0x04b2f4a1 GSEventRun + 104
    33  UIKit                               0x00e21eb9 UIApplicationMain + 160
    34  MileageLogger                       0x00055201 main + 145
    35  libdyld.dylib                       0x02d67a25 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我的代码是为TableViewController是...

My Code is for the TableViewController is...

import UIKit
import CoreData

class MileageLogsTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {

    @IBOutlet var milageLogTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            try fetchedResultsController.performFetch()
        } catch {
            let fetchError = error as NSError
            print("Unable to fetch MileageLog")
            print("\(fetchError), \(fetchError.localizedDescription)")
        }

        // Display an Edit button in the navigation bar for this view controller.
        self.navigationItem.leftBarButtonItem = self.editButtonItem()
    }

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

    // MARK: - Table view data source

    private lazy var fetchedResultsController: NSFetchedResultsController = {
        // Initialize Fetch Request
        let fetchRequest = NSFetchRequest(entityName: "MileageLog")

        // Add Sort Descriptors
        let dateSort = NSSortDescriptor(key: "tripDate", ascending: false)
        let mileSort = NSSortDescriptor(key: "startMileage", ascending: false)
        fetchRequest.sortDescriptors = [dateSort, mileSort]

        let delegate = UIApplication.sharedApplication().delegate as! AppDelegate
        let managedObjectContext = delegate.managedObjectContext

        // Initialize Fetched Results Controller
        let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: "rootCache")

        return fetchedResultsController

    }()

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        if let sections = fetchedResultsController.sections {
            return sections.count
        }

        return 0
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let sections = fetchedResultsController.sections {
            let sectionInfo = sections[section]
            return sectionInfo.numberOfObjects
        }

        return 0
    }


     override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("MileageLogCell") as! MileageTableViewCell

        // Fetch MileageLog
        if let mileageLog = fetchedResultsController.objectAtIndexPath(indexPath) as? MileageLog {
            //format date as medium style date
            let formatter = NSDateFormatter()
            formatter.dateStyle = .MediumStyle
            let logDateString = formatter.stringFromDate(mileageLog.tripDate!)
            //format NSNumber mileage to string
            let mileageInt:NSNumber = mileageLog.startMileage!
            let mileageString = String(mileageInt)

            cell.lb_LogDate.text = logDateString
            cell.lb_LogMileage.text = mileageString
            cell.lb_LogStartLocation.text = mileageLog.startLocation
            cell.lb_LogDestination.text = mileageLog.endLocation
        }
        return cell
     }


    // Override to support conditional editing of the table view.
    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return false 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) {

        switch editingStyle {

         case .Delete:
            // Delete the row from the data source
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)

        default :
            return
        }

    }
 }

我很难找到解决方案... any帮助欣赏。

I am struggling to find the solution... any help appreciated.

推荐答案

deleteRowsAtIndexPaths 只更新视图,模型,你必须在Core Data中删除对象

deleteRowsAtIndexPaths only updates the view, but not the model, you have to delete the object also in Core Data

   ...
   case .Delete:
        // Delete the row from the data source
        let objectToDelete = fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject
        let context = fetchedResultsController.managedObjectContext
        context.deleteObject(objectToDelete)
        do {
          try context.save()
          tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } catch {
           print(error)
        }

当使用 NSFetchedResultsController 时,强烈建议您使用委托方法来处理UI的更新。

When using NSFetchedResultsController it's highly recommended to implement the delegate methods to handle the update of the UI there.

这篇关于Swift UITableView删除行项 - tableview数据源是Core Data的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆