Ios 调用reloadRowsAtIndexPaths方法时导致反弹效果的动态单元格高度
背景:在表格视图中,每个单元格都包含一个按钮,显示为图像。我想显示的效果是,当我单击图像(实际上是按钮)时,按钮的图像会变为另一个。Ios 调用reloadRowsAtIndexPaths方法时导致反弹效果的动态单元格高度,ios,uitableview,core-data,Ios,Uitableview,Core Data,背景:在表格视图中,每个单元格都包含一个按钮,显示为图像。我想显示的效果是,当我单击图像(实际上是按钮)时,按钮的图像会变为另一个。 Bug:假设有很多数据(在一个页面上),如果我单击一个单元格的按钮,按钮的图像将发生变化,但会产生一个副作用,即整个tableView将首先向上滚动一点(像反弹效果),然后向下滚动到前一个位置。 我所做的: 在ViewDidLoad方法中:inboxListTableView.EstimateDrowEight=60 inboxListTableView.rowH
Bug:假设有很多数据(在一个页面上),如果我单击一个单元格的按钮,按钮的图像将发生变化,但会产生一个副作用,即整个tableView将首先向上滚动一点(像反弹效果),然后向下滚动到前一个位置。
我所做的:
inboxListTableView.EstimateDrowEight=60
inboxListTableView.rowHeight=UITableViewAutomaticDimension
func controllerWillChangeContent(controller: NSFetchedResultsController) {
inboxListTableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath!, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath!) {
switch type {
case .Insert:
inboxListTableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
case .Delete:
inboxListTableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
case .Update:
inboxListTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
default:
inboxListTableView.reloadData()
}
actions = controller.fetchedObjects as [Action]
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
inboxListTableView.endUpdates()
}
有什么想法吗?任何事都能帮上忙!谢谢:)我认为解决您问题的实用方法是简单地而不是
使用NSFetchedResultsControllerDelegate
方法进行此特定更新
您可以直接在按钮处理程序中更改按钮的图像。您必须在fetched results controller委托的.Update
案例中检查这种情况,并确保不调用重新加载rowsatindexpaths
方法
现在,您正在避免使用自动UI更新机制,因此不应出现此问题
顺便说一句,依赖表视图单元格的视图层次结构来访问索引路径(superview.superview…
)是非常糟糕的做法。几年前,苹果改变了细胞的工作方式,并打破了依赖于类似范例的代码。集合视图单元格也是如此
相反,可以这样做:
func buttonHandler(sender: UIButton) {
let point = sender.convertPoint(CGPointZero, toView:self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(point)
}
我有完全相同的问题:使用动态单元格高度时有一点反弹。我的例子的不同之处在于,我没有使用NSFetchedResultsController,而且我还更改了单元格的高度(展开和折叠)
经过大量的实验,我找到了一个简单的解决办法。只需在重新加载rowsatindexpaths后调用ScrollToRowatineXpath。这对我有用
tableView.reloadRows(at: [indexPath], with: .none)
tableView.scrollToRow(at: indexPath, at: .none, animated: true)
我在展开和折叠单元格时调用此代码。
我希望您可以在项目中使用此功能。我注意到您有行动画。无。为什么?@Mundi起初我把它设置为“.Fade”,但仍然有这个问题,所以我把它改为“.None”,我认为它可能会起作用。这与你的更新逻辑有关。您正在更改托管对象的布尔属性。基于此,您正在显示imageA或imageB。也许您应该在问题中添加CellForRowatineXpath
的实现。现在,我可以在单击按钮时更改按钮的图像,并在CellForRowatineXmethod中配置单元格的内容。问题是一切都是正确的,但tableview会反弹一点:(不过还是要谢谢你!@MundiThank你提供了获取tableView的方法!!但遗憾的是,删除“reloadRowsAtIndexPaths”方法的方式可能不起作用。我根据你的建议从两个方面修改了代码:1我删除了“.Update”开关盒。2在buttonAction方法中,我使用sender.setImage(UIImage)更改了发件人(UIButton)的图像(名称:imageName),forState:.Normal)
。现在,在运行时,相应按钮的图像可以成功更改,但tableView仍会像以前一样向上滚动。谢谢!此外,当我使用假数据(将tableView数据源存储在数组中)时,不会显示这种反弹效果,当时我使用了reloadRowsAtIndexPaths
方法。非常感谢!!@MundiSimple和伟大的解决方案
tableView.reloadRows(at: [indexPath], with: .none)
tableView.scrollToRow(at: indexPath, at: .none, animated: true)