使用tableView:moveRowAtIndexPath:toIndexPath:方法后,将新订单保存到核心数据 [英] Save new order to core data after the using the tableView:moveRowAtIndexPath:toIndexPath: method

查看:200
本文介绍了使用tableView:moveRowAtIndexPath:toIndexPath:方法后,将新订单保存到核心数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Swift iOS应用程序中有一个tableView,允许用户重新排序行。点击编辑按钮,可以重新排序或删除行,并重新点击编辑按钮(现在显示为完成)以完成该过程。

I have a tableView in a Swift iOS app that allows the user to re-order the rows. An Edit button is tapped, rows can be re-ordered or deleted, and the Edit button (which now reads Done) is re-tapped to complete the process.

如果我只是使用tableView:moveRowAtIndexPath:toIndexPath:方法,它如上所述工作,并且表格在点击Done时正确显示重新排序的行。但是当它返回到表时它不记得新的顺序,所以我在核心数据中添加了一个新的位置变量(Int),并且我已经根据它对我的表进行了排序。

If I simply use the tableView:moveRowAtIndexPath:toIndexPath: method, it works as described above and the table shows the re-ordered rows correctly when Done is tapped. But it doesn't remember the new order when returning to the table, so I added a new "position" variable (Int) in core data and I have made my table sort itself based on that.

我的问题是,在用户移动一行并点击完成后,该表会立即将自身重新命令回到以前的状态。因此,在我的代码可以正确捕获新订单并将其重新写入核心数据之前,它使用核心数据中的旧(原始)位置变量。

My problem is that after a user has moved a row and clicks Done, the table immediately re-orders itself back to how it was before. So it is using the old (original) position variables in core data, before my code can properly capture the new order and re-write it to core data.

是否存在在表重新加载之前单击Done时,是否会捕获一个使新订单被捕获的方法?

Is there a way to make this new order get captured when Done is clicked before the table reloads?

这是我处理移动的代码:

Here is my code that handles the move:

func tableView(tableView: UITableView!, moveRowAtIndexPath sourceIndexPath: NSIndexPath!, toIndexPath destinationIndexPath: NSIndexPath!) {
}

这是我按下Done时调用的代码。我遍历表格的每一行,并根据它的新行在核心数据中重新分配人物的位置变量:

And here is my code that is called when Done is pressed. I go through each row of my table and re-assign the person's position variable in core data based on it's new row:

for currentIteration in 0..<tableView.numberOfRowsInSection(0) {
    var indexPathForCurrentIteration = NSIndexPath(forRow: currentIteration, inSection: 0)
    let personAtCurrentIndexIteration = fetchedResultsController.objectAtIndexPath(indexPathForCurrentIteration) as PersonModel
    personAtCurrentIndexIteration.position = indexPathForCurrentIteration.row
    println("\(personAtCurrentIndexIteration.name) has a position value of \(personAtCurrentIndexIteration.position)")
    (UIApplication.sharedApplication().delegate as AppDelegate).saveContext()
        tableView.reloadData();
}

按下完成按钮时会调用上面的内容,但我也试过调用它在moveRowAtIndexPath方法中没有成功(相同的结果 - 当按下Done时它重新加载表的旧顺序)。我也试过注释掉reloadData而没有成功。

The above is called when the Done button is pressed, but I also tried calling it within the moveRowAtIndexPath method without success (same result - it reloads the old order of the table when Done is pressed). I have also tried commenting out reloadData without success.

我认为我的问题可能在于上面的内容没有捕获新的行顺序,而是仍然得到了旧行顺序。如果是这种情况,那么我不知道让它等待获得新行顺序的最简单方法。

I think my problem might lie in the fact that the above is not capturing the new row order, but instead still gets the old row order. If that is the case, then I don't know the simplest way to make it "wait" to get the new row order.

我开始考虑的更长的解决方法将捕获移动的行的初始和最终行值,并根据该更新相应地保留剩余行的值。有些代码在下面,但我停止了,因为我认为可能有更聪明的方法。

A longer workaround that I started considering would be to capture the moved row's initial and final row value, and based on that update the remaining rows' values accordingly. Some of that code is below but I stopped since I figured there is likely a smarter way.

if((sourceIndexPath.row > indexPathForCurrentIteration.row) && (destinationIndexPath.row > indexPathForCurrentIteration.row)) {
    //if the moved row was ahead of this row before AND after the move, do nothing (don't change this row's position value)
    //println("\(personAtCurrentIndexIteration.name)'s position was unchnaged")
} else if((sourceIndexPath.row > indexPathForCurrentIteration.row) && (destinationIndexPath.row < indexPathForCurrentIteration.row)) {
    //if the moved row was ahead of this row before BUT behind it after the move, then this row's position value needs to be bumped up one number
    personAtCurrentIndexIteration.position = indexPathForCurrentIteration.row+1
//Etc...

谢谢提前获得任何帮助。

Thanks in advance for any help you can provide.

推荐答案


  1. 添加到CoreDataorderPosition类型的Int属性并将orderPosition添加到模型文件中。

  1. Add to CoreData "orderPosition" type Int attribute and add orderPosition to your Model file.

当您向CoreData添加一些数据时,还要添加orderPosition值

When you add some data to your CoreData, add also orderPosition value

  let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
  let contxt: NSManagedObjectContext = appDel.managedObjectContext!
  let en = NSEntityDescription.entityForName("MyCoreData", inManagedObjectContext: contxt)
  let freq = NSFetchRequest(entityName: "MyCoreData")
  var MyData = contxt.executeFetchRequest(freq, error: nil)!
  var newItem = Model(entity: en!, insertIntoManagedObjectContext: contxt)
  var newOrderPosition = MyData.count


  //here you add some data to your CoreData
  //and also you must add new order position
  newItem.orderPosition = orderPosition


  • 在TableView中,您必须创建一个函数,该函数将对您将在TableView中显示的数组进行排序。这样的事情:

  • In your TableView you must create a function that will sort an array that you will display in your TableView. Something like this:

        func RefreshCoredata()
    {
        let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        let freq = NSFetchRequest(entityName: "MyCoreData")
        let contxt: NSManagedObjectContext = appDel.managedObjectContext!
    
        let sortDescriptor = NSSortDescriptor(key: "orderPosition", ascending: true)
        freq.sortDescriptors = [sortDescriptor]
        MyData = contxt.executeFetchRequest(freq, error: nil)!
    
    } 
    


  • 请记住,您必须始终对数组进行排序把他送到桌旁!

  • Remember, you must always sort your array before send him to table!

    当你想重新排序表行时你必须做什么? :

    What you must do when you want to reordering your table rows? :

    override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
     }
    
    override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
    
    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    let contxt: NSManagedObjectContext = appDel.managedObjectContext!
    
    RefreshCoredata()
    
    
    if fromIndexPath.row > toIndexPath.row
    {
        for i in toIndexPath.row..<fromIndexPath.row
    
        {
            MyData[i].setValue(i+1, forKey: "orderPosition")
    
    
        }
    
        MyData[fromIndexPath.row].setValue(toIndexPath.row, forKey: "orderPosition")
    }
    if fromIndexPath.row < toIndexPath.row
    {
    
        for i in fromIndexPath.row + 1...toIndexPath.row
    
        {
            MyData[i].setValue(i-1, forKey: "orderPosition")
    
    
        }
    
        MyData[fromIndexPath.row].setValue(toIndexPath.row, forKey: "orderPosition")
    
    
    
    }
    
    contxt.save(nil)
    
    RefreshCoredata()
    
    }
    


  • 这需要重置你的订单位置CoreData

    This need to reset ordering position in your CoreData


    1. 当你想删除一些表行时你必须做什么?

    1. What you must do when you want to delete some table rows?

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle:
    UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
    {
    if editingStyle == .Delete {
    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    let contxt: NSManagedObjectContext = appDel.managedObjectContext!
    RefreshCoredata()
    contxt.deleteObject(MyData[indexPath.row] as NSManagedObject)
    for i in indexPath.row + 1..<MyData.count
            {
                MyData[i].setValue(i-1, forKey: "orderPosition")
            }
    RefreshCoredata()
    
     tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
     contxt.save(nil)
    
     }
    


    这就是全部!

    这篇关于使用tableView:moveRowAtIndexPath:toIndexPath:方法后,将新订单保存到核心数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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