I have a navigation controller, its root view controller is of type CollectionViewControllerA
. Upon selecting an item, I have a fade out and expanding animation followed by a call to push a second view controller of type CollectionVewControllerB
onto the stack:
CollectionViewControllerB *b = ... // construction of the view controller to be pushed
[UIView animateWithDuration:.3
animations:^{
self.collectionView.transform = CGAffineTransformMakeScale(1.5, 1.5);
self.collectionView.alpha = 0;
}
completion:^(BOOL s){
[self.navigationController pushViewController:b animated:NO];
}];
I pop the view controller in a similar way
[UIView animateWithDuration:.3
animations:^{
self.collectionView.transform = CGAffineTransformMakeScale(.3, .3);
self.collectionView.alpha = 0;
}
completion:^(BOOL s){
[self.navigationController popViewControllerAnimated:NO];
}];
The problem here is that the app crashes when popping the view controller. Reason:
*** -[CollectionViewControllerB scrollViewDidScroll:]: message sent to deallocated instance
I understand that the problem is because the popped view controller is destroyed, but why does scrollViewDidScroll:
get called in the first place? Nothing changes the contentOffset
of the collectionView
in code, and there is no user interaction either. Unless changing the transform
property also triggers the method to get called?
CollectionViewControllerB
implements scrollViewDidScroll:
because I need to disable vertical scrolling.
Meanwhile I have a very very messy hack to prevent the crash, that is before the animation, I add
self.collectionView.delegate = nil;
This stops the method from getting called. But there has to be a better way.
Can anyone shed some light on why scrollViewDidScroll:
is called and how it can be stopped?
It seems like the only way to solve the problem is what I have already done... setting the delegate to nil before the animation.
self.collectionView.delegate = nil;
Hopefully this helps someone else in the future.