滑动删除 UITableView 单元格动画在 swift 2 中不起作用
Posted
技术标签:
【中文标题】滑动删除 UITableView 单元格动画在 swift 2 中不起作用【英文标题】:swipe to delete UITableView cell animation is not working in swift 2 【发布时间】:2015-10-05 14:55:35 【问题描述】:滑动删除功能工作正常,但我无法添加动画,我尽我所能但没有任何效果。每当我添加动画代码时,删除单元格时应用程序就会崩溃。如果再次加载应用程序,会发现记录被删除,说明删除成功。
我得到的崩溃错误是:
无效更新:第 0 节中的行数无效。 更新 (1) 后包含在现有节中的行必须是 等于该节之前包含的行数 update (1),加上或减去插入或删除的行数 该部分(0 插入,1 删除)和加或减的数量 移入或移出该部分的行(0 移入,0 移出)。
我尝试的动画代码块是:
//1
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
//2
tableView.deleteRowsAtIndexPaths([indexPath],
withRowAnimation: UITableViewRowAnimation.Automatic)
我也尝试删除这些代码,但也没有用:
fetchAndSetResults() treatmentProtocolsTableView.reloadData()
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()
感谢您的帮助
【问题讨论】:
【参考方案1】:你需要封装在beginUpdates()
和endUpdates()
里面。此外,更新用于加载表格视图的数据模型:
self.tableView.beginUpdates()
self.txProtocols.removeObjectAtIndex(indexPath.row) // Check this out
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
self.tableView.endUpdates()
【讨论】:
谢谢 Abhinav,将“if editingstyle”代码封装在开始和结束更新中,并在您的解决方案中添加第三行代码。我不得不删除第二行。我不知道这是否是最佳做法,因为我是 swift 新手,但它工作正常。再次感谢!【参考方案2】:根据Abhinav 接受的答案,这是我的解决方案(Swift 3)。这在我的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()
【讨论】:
以上是关于滑动删除 UITableView 单元格动画在 swift 2 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
在 UITableView 单元格滑动中选择“删除”,但未调用“提交编辑样式”
iOS 7 UITableView 问题 - 当我们已经有一个单元格时尝试设置滑动以删除单元格
在 iphone sdk 中一起滑动以删除和移动 UItableView 选项中的单元格