UICollectionView调用scrollViewDidScroll:从导航堆栈弹出时

时间:2013-03-05 05:06:00

标签: ios uiscrollview uinavigationcontroller crash uicollectionview

我有一个导航控制器,其根视图控制器的类型为CollectionViewControllerA。在选择一个项目后,我有一个淡出和扩展动画,然后调用将第CollectionVewControllerB类型的第二个视图控制器推入堆栈:

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];
                 }];

我以类似的方式弹出视图控制器

[UIView animateWithDuration:.3
                 animations:^{
                     self.collectionView.transform = CGAffineTransformMakeScale(.3, .3);
                     self.collectionView.alpha = 0;
                 }
                 completion:^(BOOL s){
                     [self.navigationController popViewControllerAnimated:NO];
                 }];

这里的问题是弹出视图控制器时应用程序崩溃了。原因:

*** -[CollectionViewControllerB scrollViewDidScroll:]: message sent to deallocated instance

我理解问题是因为弹出的视图控制器被破坏了,但为什么scrollViewDidScroll:首先被调用?代码中contentOffset的{​​{1}}没有任何变化,也没有用户互动。除非更改collectionView属性也会触发调用方法吗?

transform实现CollectionViewControllerB因为我需要禁用垂直滚动。

同时我有一个非常凌乱的黑客来防止崩溃,那是在动画之前,我添加

scrollViewDidScroll:

这会阻止方法被调用。但必须有更好的方法。

任何人都可以了解为什么调用self.collectionView.delegate = nil; 以及如何停止它?

3 个答案:

答案 0 :(得分:56)

似乎解决问题的唯一方法就是我已经做过的事情......在动画之前将委托设置为nil。

self.collectionView.delegate = nil;

希望将来可以帮助其他人。

答案 1 :(得分:9)

在视图控制器中设置self.automaticallyAdjustsScrollViewInsets = NO;

我遇到了类似的问题,发现在离开页面时,contentOffset每次都会改变20。

我发现在我的视图控制器中设置此属性会停止此更改,因此不再调用scrollViewDidScroll。事实证明,视图控制器会自动调整内容插入,以便更改状态栏,导航栏等。即使您离开也是如此。

我认为这是一个更好的解决方案和正确解释为什么要调用滚动方法。

答案 2 :(得分:0)

您可以在控制器中尝试此操作。

[self setEdgesForExtendedLayout:UIRectEdgeNone];

希望这会对你有所帮助。