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

All*_*eng 27 crash uiscrollview uinavigationcontroller ios 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];
                 }];
Run Code Online (Sandbox Code Playgroud)

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

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

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

*** -[CollectionViewControllerB scrollViewDidScroll:]: message sent to deallocated instance
Run Code Online (Sandbox Code Playgroud)

我知道问题是因为弹出的视图控制器被破坏了,但为什么scrollViewDidScroll:首先调用它?没有改变contentOffsetcollectionView代码,并没有用户交互无论是.除非更改transform属性也会触发调用方法?

CollectionViewControllerB实现,scrollViewDidScroll:因为我需要禁用垂直滚动.

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

self.collectionView.delegate = nil;
Run Code Online (Sandbox Code Playgroud)

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

任何人都可以阐明为什么scrollViewDidScroll:被召唤以及如何阻止它?

All*_*eng 56

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

self.collectionView.delegate = nil;
Run Code Online (Sandbox Code Playgroud)

希望这有助于将来的其他人.

  • 我在 - (void)dealloc方法中添加了它. (9认同)
  • 我刚刚用UITableView发生了这件事.我不知道为什么,但将委托设置为nil修复它.但是,由于某种原因,感觉就像一个黑客. (3认同)

jac*_*ley 9

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

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

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

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