简体   繁体   English

滑动以删除UITableView单元格动画在swift 2中不起作用

[英]swipe to delete UITableView cell animation is not working in swift 2

The swipe delete functionality is working fine, but i'm not able to add the animation, i tried everything i can but nothing worked. 滑动删除功能运行良好,但我无法添加动画,我已尽我所能,但无济于事。 Whenever I add the code for animation, the app crashes when the cell is deleted. 每当我添加动画代码时,删除单元格时应用程序就会崩溃。 If you load the application again, you will find that the record was deleted, implying that the deletion was successful. 如果再次加载该应用程序,则会发现该记录已删除,这意味着删除成功。

The crash error i'm getting is: 我收到的当机错误是:

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, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). 无效的更新:第0节中的行数无效。更新(1)之后,现有节中包含的行数必须等于更新(1)之前该节中包含的行数。从该部分插入或删除的行数(已插入0,已删除1),加上或减去移入或移出该部分的行数(移入0,移出0)。

The animation code blocks i tried were: 我尝试的动画代码块是:

        //1
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        //2
        tableView.deleteRowsAtIndexPaths([indexPath],
            withRowAnimation: UITableViewRowAnimation.Automatic)

I also tried to remove those codes and it didn't work too: 我还尝试删除了这些代码,但也无法正常工作:

fetchAndSetResults() treatmentProtocolsTableView.reloadData() fetchAndSetResults()treatmentProtocolsTableView.reloadData()

The entire code in the swift file is here, I commented out the animation blocks, and it works properly. swift文件中的整个代码在这里,我注释掉了动画块,并且可以正常工作。

import UIKit
import CoreData

class Tx_Protocols: UIViewController, UITableViewDataSource, UITableViewDelegate {

    //MARK: declaratoins.
    weak var secureTextAlertAction: UIAlertAction?

    //MARK: Core data related
    var txProtocols = [TreatmentProtocolData]()
    var selectedProtocol : TreatmentProtocolData? = nil

    @IBOutlet weak var treatmentProtocolsTableView: UITableView!


    //When button + is clicked, segue show add tx VC is initiated.
    @IBAction func plusButtonAddTxProtocol(sender: AnyObject) {
        self.performSegueWithIdentifier("showAddTxVC", sender: self)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        fetchAndSetResults()

        treatmentProtocolsTableView.delegate = self
        treatmentProtocolsTableView.dataSource = self
    }

    //When this is used, the data shows with a slight lag, slower.
    override func viewDidAppear(animated: Bool) {
        fetchAndSetResults()
        treatmentProtocolsTableView.reloadData()
    }

    //This is how you catch the app delegate core data fnxnality, GRABBING THE PROPERTY IN APP DELEGATE
    func fetchAndSetResults() {
        let app = UIApplication.sharedApplication().delegate as! AppDelegate
        let context = app.managedObjectContext
        let fetchRequest  = NSFetchRequest(entityName: "TreatmentProtocolData")

        do {
            let results = try context.executeFetchRequest(fetchRequest)
            self.txProtocols = results as! [TreatmentProtocolData]
        } catch let err as NSError {
            print(err.debugDescription)
        }
    }



    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier:"Cell")
        cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
        cell.textLabel!.adjustsFontSizeToFitWidth = true
        cell.textLabel!.font = UIFont.boldSystemFontOfSize(17)

        let treatmentProtocol = txProtocols[indexPath.row]
        cell.textLabel!.text = treatmentProtocol.title
        cell.imageView?.image = treatmentProtocol.getTxProtocolImage()

        return cell
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return txProtocols.count
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        self.selectedProtocol = txProtocols[indexPath.row]
        self.performSegueWithIdentifier("showTxProtocol", sender: self)


    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        if segue.identifier == "showTxProtocol" {
        let detailVC = segue.destinationViewController as! ShowTxProtocolDetailVC
        detailVC.txProtocol = self.selectedProtocol
        }
    }


    //MARK: Edittable table, delete button functionality.
    func tableView(tableView: UITableView,
        canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
            return true
    }

    func tableView(tableView: UITableView,
        commitEditingStyle
        editingStyle: UITableViewCellEditingStyle,
        forRowAtIndexPath indexPath: NSIndexPath) {

            if editingStyle == UITableViewCellEditingStyle.Delete {

                let app = UIApplication.sharedApplication().delegate as! AppDelegate
                let context = app.managedObjectContext
                //1
                let protocolToRemove =
                txProtocols[indexPath.row]

                //2
                context.deleteObject(protocolToRemove)

                //3
                do {
                    try context.save()
                } catch let error as NSError {
                    print("Could not save: \(error)")
                }

//                //1
//                tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
//                //2
//                tableView.deleteRowsAtIndexPaths([indexPath],
//                    withRowAnimation: UITableViewRowAnimation.Automatic)

                fetchAndSetResults()
                treatmentProtocolsTableView.reloadData()

            }
    }


}

I appreciate your help 我感谢您的帮助

You need to encapsulate inside beginUpdates() and endUpdates() . 您需要封装在beginUpdates()endUpdates() Also, update your data model that is used to load the table view: 另外,更新用于加载表视图的数据模型:

self.tableView.beginUpdates()
self.txProtocols.removeObjectAtIndex(indexPath.row) // Check this out 
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
self.tableView.endUpdates()

Based on the accepted answer by Abhinav , here was my solution (Swift 3). 根据Abhinav接受的答案,这是我的解决方案(快速3)。 This implemented in my NSFetchedResultsControllerDelegate : 这在我的NSFetchedResultsControllerDelegate实现:

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

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    ...
    case .delete:
            // Delete from tableView
            removeFromSetsToDisplayByID(removeThisSet: myObject)
            tableView.deleteRows(at: [indexPath!], with: UITableViewRowAnimation.automatic)
    ...
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM