Search code examples
iosswiftuicollectionviewuikitfbsnapshottestcase

UICollectionView performBatchUpdates completion not called while off screen


I'm using snapshot testing for my view controller. This is how the view controller is initialized in tests:

window.addSubview(viewController.view) // simulate the view is visible (probably unnecessary)
viewController.view.frame = self.snapshotFrame // set frame
viewController.beginAppearanceTransition(true, animated: false) // simulate VC's life cycle
viewController.endAppearanceTransition()

My view controller contains UICollectionView. When I perform collection view updates using performBatchUpdates, even though the update block is finished, the completion is never called.

// Animate udpates
self.collectionView.performBatchUpdates({
      // is called 
}, completion: { _ in
      // never called
})

I think it's related to the off screen rendering of the collection view. Does someone have any experience with similar issue? What am I missing to convince UICollectionView that it's on screen?


Solution

  • I found the problem. It was all about a proper timing. The test case finished before the completion was called and the view controller was deallocated.

    I speeded up collection view animations by setting

    viewController.view.layer.speed = 100 // speed up animations
    

    and increased timeout for the test case to 0.1 seconds. Everything works as expected now.