使用Swift 4使用fetchedResultsController重新排序TableView

问题描述 投票:0回答:1

我想做的是重新排列我的tableview单元格。我的表格视图包含以下部分:数据模型简单:产品列表,每个产品都有一个类别。

我使用的是UITableViewDropDelegate,UITableViewDragDelegate,因为我不喜欢tableview中的编辑模式(红色按钮使我发疯):

   func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {


    var objects = self.fetchedResultsController.fetchedObjects! as [TblProduits]
    self.fetchedResultsController.delegate = nil

    //get the destination section
    let myDestSection = objects[destinationIndexPath.row]

    let object = objects[sourceIndexPath.row]
    objects.remove(at: sourceIndexPath.row)

    //updating product categorie with the destination categorie before inserting 
    object.categorie = myDestSection.categorie

    objects.insert(object, at: destinationIndexPath.row)


    fctSaveListDesProduits()
    self.fetchedResultsController.delegate = self
  } 

当我尝试将产品放入另一部分时出现此错误时,我的应用程序在此功能上崩溃:

由于未捕获的异常'NSInternalInconsistencyException',原因:'无效的更新:第0节中的行数无效。更新(5)之后现有节中包含的行数必须等于该行中包含的行数更新(5)之前的部分,加上或减去从该部分插入或删除的行数(已插入0,已删除0),加上或减去该部分移入或移出的行数(移入1,移0) )。'

我该如何解决?

更新

这里是完整代码:

 @IBOutlet var TblView_Produit: UITableView!

let Mycontext =  (UIApplication.shared.delegate   as! AppDelegate).persistentContainer.viewContext
let Myrequest : NSFetchRequest<TblProduits> = TblProduits.fetchRequest()
var fetchedResultsController : NSFetchedResultsController<TblProduits>!
var managedObjectContext: NSManagedObjectContext? = nil

override func viewDidLoad() {
    super.viewDidLoad()

     TblView_Produit.dragDelegate = self
    TblView_Produit.dropDelegate = self
   TblView_Produit.dragInteractionEnabled = true

    // Load Data
    Fct_loadListDesProduits()
    fetchedResultsController.delegate = self

}

func Fct_SaveListDesProduits() {
    do {
        try Mycontext.save()
        //    print ("saved ligne \(i)")
    } catch {
        debugPrint ("there is an error  \(error.localizedDescription)")
    }
}

  func Fct_loadListDesProduits () {



    let MySortDescriptor = NSSortDescriptor(key: #keyPath(TblProduits.categorie.categorie_Name), ascending: true)
    Myrequest.sortDescriptors = [MySortDescriptor]
    fetchedResultsController = NSFetchedResultsController(fetchRequest: Myrequest, managedObjectContext: Mycontext, sectionNameKeyPath:  #keyPath(TblProduits.categorie.categorie_Name), cacheName: nil)

    do {
        try  fetchedResultsController.performFetch()

    } catch {
        debugPrint ("there is an error  \(error.localizedDescription)")

    }
}


   func numberOfSections(in tableView: UITableView) -> Int {
    guard let sections = self.fetchedResultsController.sections else {
        return 0
    }

    return sections.count
}

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    guard let sections = self.fetchedResultsController.sections else {
        return 0
    }

    return sections[section].numberOfObjects
}

  func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    guard let sections = self.fetchedResultsController.sections else {
        return ""
    }

    return sections[section].name
}


// MARK: - FetchedResultsController Delegate

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

    switch(type) {
    case .insert:
        if  let Myindexpath = newIndexPath {

            self.TblView_Produit.insertRows(at: [Myindexpath], with: .left)

        }
        break;

    case .delete:
        if let MyindexPath = indexPath {
            TblView_Produit.deleteRows(at: [MyindexPath], with: .fade)
        }
        break;

    case .move:


        break;
    case .update:


        break;
    }



}


func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    TblView_Produit.endUpdates()
}

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    TblView_Produit.beginUpdates()
}



func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! ProduitTableViewCell
    if let ProduitName = self.fetchedResultsController.object(at: indexPath).produit_name { //ProductTable[indexPath.row].produit_name{


        cell.SetListeDesProduits(ProduitName: ProduitName)
    }
    //    cell.isEditing =  self.tableView(tableView, canMoveRowAt: indexPath)
    return cell
}


     func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {


var objects = self.fetchedResultsController.fetchedObjects! as [TblProduits]
self.fetchedResultsController.delegate = nil

//get the destination section
let myDestSection = objects[destinationIndexPath.section]

let object = objects[sourceIndexPath.row]
objects.remove(at: sourceIndexPath.row)

//updating product categorie with the destination categorie before inserting 
object.categorie = myDestSection.categorie

objects.insert(object, at: destinationIndexPath.row)


fctSaveListDesProduits()
self.fetchedResultsController.delegate = self
  } 

更新

登录数Ofrowinsection:

我只有三个部分,每个部分只有一个项目

section :  2
sections[section].numberOfObjects: 1
section :  0
sections[section].numberOfObjects: 1
section :  1
sections[section].numberOfObjects: 1
section :  2
sections[section].numberOfObjects: 1
section :  0
sections[section].numberOfObjects: 1
section :  1
sections[section].numberOfObjects: 1
section :  2
sections[section].numberOfObjects: 1
section :  0
sections[section].numberOfObjects: 1
section :  1
sections[section].numberOfObjects: 1
section :  2
sections[section].numberOfObjects: 1
section :  0
sections[section].numberOfObjects: 1
section :  1
sections[section].numberOfObjects: 1

当我执行从第二部分到第一部分的拖放操作时>>

section 
section :  0
sections[section].numberOfObjects: 1
section :  1
sections[section].numberOfObjects: 1
section :  2
sections[section].numberOfObjects: 1

018-01-26 19:56:05.492956+0100 ShopTogether[8815:1168659] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/UITableView.m:2011
2018-01-26 19:56:05.513608+0100 ShopTogether[8815:1168659] *** 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 (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (1 moved in, 0 moved out).'

//更新Fetchcontroller

我认为问题出在显示这些部分时

实际上,当我在sectionNameKeyPath中放置nil时:nil ==>我的表视图不再有任何部分,并且也不再崩溃但是我希望在我的表视图中有一些部分

 fetchedResultsController = 
   NSFetchedResultsController(fetchRequest: Myrequest, managedObjectContext: Mycontext,
   sectionNameKeyPath: nil, cacheName: nil)

我仍在寻找答案,但我希望在不同的[[tableview中允许各节之间进行拖放

我想做的是重新排列我的tableview单元格。我的表格视图包含以下部分:数据模型简单:产品列表,每个产品都有一个类别。我正在使用UITableViewDropDelegate,...
ios uitableview core-data nsfetchedresultscontroller swift4
1个回答
0
投票

[我不确定这是否是最干净的方法

,但是我通过在更新类别之后重新生成TableView并插入对象来解决了我的问题。
© www.soinside.com 2019 - 2024. All rights reserved.