我有一个由NSFetchedResultsController驱动的CollectionView。
CollectionViewLayout是按升序排序的单元格的水平“轮播”布局。
新项目插入海关动画。
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
if type == NSFetchedResultsChangeType.Insert {
println("Insert Object: \(newIndexPath)")
UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveEaseOut, animations: {
self.collectionView?.insertItems(at: [newIndexPath])
}, completion: { finished in
self.collectionView?.scrollToItem(at: newIndexPath, at: .centeredHorizontally, animated: true)
})
)
...
它有效,但动画有点毛刺,滚动同时发生。
我想滚动到Item然后插入自定义动画,但如果我插入它之前滚动到项目应用程序崩溃。
这里做什么是正确的?
谢谢
我要尝试的第一件事是用animate(withDuration:delay:options:animations:completion:)
替换performBatchUpdates(_:completion:)
func controller(controller: NSFetchedResultsController,
didChangeObject anObject: AnyObject,
atIndexPath indexPath: NSIndexPath?,
forChangeType type: NSFetchedResultsChangeType,
newIndexPath: NSIndexPath?)
{
if type == NSFetchedResultsChangeType.Insert {
println("Insert Object: \(newIndexPath)")
self.collectionView?.performBatchUpdates({
self.collectionView?.insertItems(at: [newIndexPath])
}, completion: { finished in
self.collectionView?.scrollToItem(at: newIndexPath, at: .centeredHorizontally, animated: true)
})
…
}
如果这仍然给你带来问题,那么你可以在下一个运行循环中调用滚动。
func controller(controller: NSFetchedResultsController,
didChangeObject anObject: AnyObject,
atIndexPath indexPath: NSIndexPath?,
forChangeType type: NSFetchedResultsChangeType,
newIndexPath: NSIndexPath?)
{
if type == NSFetchedResultsChangeType.Insert {
println("Insert Object: \(newIndexPath)")
self.collectionView?.performBatchUpdates({
self.collectionView?.insertItems(at: [newIndexPath])
}, completion: { finished in
DispatchQueue.main.async { // Defer to next runlop.
self.collectionView?.scrollToItem(at: newIndexPath, at: .centeredHorizontally, animated: true)
}
})
…
}
最后,您可以尝试仅动画滚动部分。
func controller(controller: NSFetchedResultsController,
didChangeObject anObject: AnyObject,
atIndexPath indexPath: NSIndexPath?,
forChangeType type: NSFetchedResultsChangeType,
newIndexPath: NSIndexPath?)
{
if type == NSFetchedResultsChangeType.Insert {
println("Insert Object: \(newIndexPath)")
self.collectionView?.reloadItems(at: [newIndexPath]) // reload without animating.
DispatchQueue.main.async { // Defer to next runlop.
self.collectionView?.scrollToItem(at: newIndexPath, at: .centeredHorizontally, animated: true)
}
…
}
从功能上看,我可以想象你看到的故障是CollectionView向前滚动然后橡皮筋/“传送”回来。
我想这可能会发生,因为你试图同时运行两个动画。您的第一个动画UIView.animate()将滚动动画为新插入的项目;但是,当你调用collectionView?.scrollToItem()时,你也可以为它设置动画(见下文)
self.collectionView?.scrollToItem(..., animated: true) <--
这可能就是为什么它不起作用;你正试图动画动画。尝试将动画设置为false,看看是否修复了它。