27

我有一个导航控制器,它的根视图控制器的类型是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:首先调用呢?没有任何改变in 代码contentOffsetcollectionView也没有用户交互。除非更改transform属性也会触发方法被调用?

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

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

self.collectionView.delegate = nil;

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

任何人都可以阐明为什么scrollViewDidScroll:被调用以及如何停止它?

4

3 回答 3

56

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

self.collectionView.delegate = nil;

希望这对将来的其他人有所帮助。

于 2013-07-25T05:07:18.333 回答
9

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

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

我发现在我的视图控制器中设置这个属性停止了这种变化,因此scrollViewDidScroll不再被调用。结果是视图控制器会自动调整内容插入以适应状态栏、导航栏等的变化。即使您离开。

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

于 2014-12-02T15:11:40.593 回答
0

你可以在你的控制器中试试这个。

[self setEdgesForExtendedLayout:UIRectEdgeNone];

希望这会对你有所帮助。

于 2016-04-15T05:02:32.087 回答