CollectionView滚动到新插入的项目

问题描述 投票:0回答:2

我有一个由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然后插入自定义动画,但如果我插入它之前滚动到项目应用程序崩溃。

这里做什么是正确的?

谢谢

swift animation uicollectionview nsfetchedresultscontroller
2个回答
0
投票

我要尝试的第一件事是用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)
    }
    …
}

0
投票

从功能上看,我可以想象你看到的故障是CollectionView向前滚动然后橡皮筋/“传送”回来。

我想这可能会发生,因为你试图同时运行两个动画。您的第一个动画UIView.animate()将滚动动画为新插入的项目;但是,当你调用collectionView?.scrollToItem()时,你也可以为它设置动画(见下文)

self.collectionView?.scrollToItem(..., animated: true) <--

这可能就是为什么它不起作用;你正试图动画动画。尝试将动画设置为false,看看是否修复了它。

© www.soinside.com 2019 - 2024. All rights reserved.