我會先說我是Xcode/Swift中製作應用程序的非常新手。我從來沒有用Obj-C做過任何事情,所以Swift是我第一次進入iOS編碼領域。刪除核心數據中的記錄後,無法刪除索引處的表格行
我的問題是,我試圖刪除核心數據記錄後刪除表格單元格。我似乎能夠刪除Core數據,但每次嘗試刪除單元格行時都會得到相同的錯誤。
我得到的錯誤如下:
2016年3月10日08:49:56.484 EZ列表[31764:3225607] *在斷言失敗 - [UITableView的_endCellAnimationsWithContext:]/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UITableView.m:1720 2016-03-10 08:49:56.487 EZ列表[31764:3225607] *終止應用到期未捕獲異常'NSInternalInconsistencyException',原因:'無效更新:第0節中的行數無效。更新(2)後現有節中包含的行數必須等於該節之前包含的行數更新(2),加號或minu s從該部分插入或刪除的行數(0插入,1刪除)以及正數或負數移入或移出該部分的行數(移入0,移出0)。 [...等等]
而且我使用刪除代碼是這樣的:
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .Destructive, title: "Delete") { (action, indexPath) in
// delete item at indexPath
let request = self.fetchRequest()
var fetchResults = [AnyObject]()
do {
fetchResults = try self.moc.executeFetchRequest(request)
} catch {
fatalError("Fetching Data to Delete Failed")
}
self.moc.deleteObject(fetchResults[indexPath.row] as! NSManagedObject)
fetchResults.removeAtIndex(indexPath.row)
do {
try self.moc.save()
} catch {
fatalError("Failed to Save after Delete")
}
self.lists.removeAtIndex(indexPath.row)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
let edit = UITableViewRowAction(style: .Normal, title: "Edit") { (action, indexPath) in
// edit item at indexPath
}
edit.backgroundColor = UIColor.init(red: 84/255, green: 200/255, blue: 214/255, alpha: 1)
return [delete, edit]
}
測試一堆我已驗證該問題是否與
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
後
但我不明白爲什麼它認爲部分行是無效的。任何幫助將不勝感激。到目前爲止,我所有的搜索都提出了Obj-C的答案或者很快的答案,這些答案似乎並沒有解決我的問題。
編輯: 添加代碼numberOfRowsInSection
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if let sections = frc.sections {
let currentSection = sections[section]
return currentSection.numberOfObjects
}
return 0
}
EDIT2: 這裏是我的ViewController 全碼**請記住,我一直在嘗試一些不同的東西來得到它的工作所以有一些評論的東西在那裏。
import UIKit
import CoreData
class ListTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var frc: NSFetchedResultsController = NSFetchedResultsController()
var lists : [Lists] = []
/*
var listNames: [String] = ["Any List", "Other List"]
var listItemCount: [Int] = [5, 6]
var listIcons: [UIImage] = [UIImage(named: "Generic List")!, UIImage(named: "Generic List")!]
*/
override func viewWillAppear(animated: Bool) {
let imageView = UIImageView(image: UIImage(named: "TableBackground"))
imageView.contentMode = .ScaleAspectFill
self.tableView.backgroundView = imageView
self.tableView.tableFooterView = UIView(frame: CGRectZero)
do {
self.lists = try moc.executeFetchRequest(fetchRequest()) as! [Lists]
} catch {
fatalError("Failed setting lists array to fetch request")
}
self.tableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
checkAnyList()
frc = getFCR()
frc.delegate = self
do {
try frc.performFetch()
} catch {
fatalError("Failed to perform inital fetch")
}
self.tableView.reloadData()
// Uncomment the following line to preserve selection between presentations
//self.clearsSelectionOnViewWillAppear = true
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func viewDidAppear(animated: Bool) {
checkAnyList()
frc = getFCR()
frc.delegate = self
do {
try frc.performFetch()
} catch {
fatalError("Failed to perform inital fetch")
}
self.tableView.reloadData()
}
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 Incomplete implementation, return the number of sections
if let sections = frc.sections {
return sections.count
}
return 0
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.backgroundColor = UIColor.clearColor()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if let sections = frc.sections {
let currentSection = sections[section]
return currentSection.numberOfObjects
}
return 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let listCellReturn = tableView.dequeueReusableCellWithIdentifier("listCell", forIndexPath: indexPath) as! ListTableViewCell
//let list = frc.objectAtIndexPath(indexPath) as! Lists
let list = self.lists[indexPath.row]
listCellReturn.separatorInset = UIEdgeInsets(top: 0, left: 78, bottom: 0, right: 0)
listCellReturn.listNameLabel.text = list.name
listCellReturn.listIconImage.image = UIImage(data: (list.image)!)
/*
listCellReturn.listNameLabel.text = listNames[indexPath.row]
listCellReturn.itemCountLabel.text = "Items: \(listItemCount[indexPath.row])"
listCellReturn.listIconImage.image = listIcons[indexPath.row]
*/
return listCellReturn
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .Destructive, title: "Delete") { (action, indexPath) in
// delete item at indexPath
let request = self.fetchRequest()
var fetchResults = [AnyObject]()
do {
fetchResults = try self.moc.executeFetchRequest(request)
} catch {
fatalError("Fetching Data to Delete Failed")
}
self.moc.deleteObject(fetchResults[indexPath.row] as! NSManagedObject)
fetchResults.removeAtIndex(indexPath.row)
do {
try self.moc.save()
} catch {
fatalError("Failed to Save after Delete")
}
self.lists.removeAtIndex(indexPath.row)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
let edit = UITableViewRowAction(style: .Normal, title: "Edit") { (action, indexPath) in
// edit item at indexPath
}
edit.backgroundColor = UIColor.init(red: 84/255, green: 200/255, blue: 214/255, alpha: 1)
return [delete, edit]
}
func fetchRequest() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "Lists")
let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
return fetchRequest
}
func getFCR() -> NSFetchedResultsController {
frc = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
return frc
}
func checkAnyList() {
var exists: Bool = false
let fetchReq = NSFetchRequest(entityName: "Lists")
let pred = NSPredicate(format: "%K == %@", "name", "Any List")
fetchReq.predicate = pred
do {
let check = try moc.executeFetchRequest(fetchReq)
for rec in check {
if let name = rec.valueForKey("name") {
if (name as! String == "Any List") {
exists = true
}
}
}
if (exists == false) {
let entityDesc = NSEntityDescription.entityForName("Lists", inManagedObjectContext: moc)
let list = Lists(entity: entityDesc!, insertIntoManagedObjectContext: moc)
list.name = "Any List"
list.image = UIImagePNGRepresentation(UIImage(named: "Any List")!)
do {
try moc.save()
} catch {
fatalError("New list save failed")
}
}
} catch {
fatalError("Error checking for Any List")
}
//let check = try moc.executeFetchRequest(fetchReq)
//for rec in check {
//} catch {
}
/*
// 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) {
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 false 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?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
請原諒,我不能完全理解。但我知道我確實會提到你提到的那條線,它看起來甚至是一樣的。但是我會在哪裏放置numberOfRows:inSection? –
我已更新我的答案,以添加有關我詢問的方法的更多詳細信息。你有沒有實現這個方法:https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection: – Mark
哦,是的,我沒有添加到我原來的帖子。 –