UICollectionView 调用 scrollViewDidScroll:从导航堆栈中弹出时
Posted
技术标签:
【中文标题】UICollectionView 调用 scrollViewDidScroll:从导航堆栈中弹出时【英文标题】:UICollectionView calling scrollViewDidScroll: when popped from the navigation stack 【发布时间】:2013-02-19 09:47:37 【问题描述】:我有一个导航控制器,它的根视图控制器的类型是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:
?代码中collectionView
的contentOffset
没有任何变化,也没有用户交互。除非更改transform
属性也会触发方法被调用?
CollectionViewControllerB
实现 scrollViewDidScroll:
因为我需要禁用垂直滚动。
同时我有一个非常非常混乱的 hack 来防止崩溃,也就是在动画之前,我添加了
self.collectionView.delegate = nil;
这会阻止该方法被调用。但必须有更好的方法。
谁能解释为什么调用scrollViewDidScroll:
以及如何停止它?
【问题讨论】:
我刚刚遇到了同样的问题,但使用了 segues。我的解决方案和你的一样;在 viewWillDisappear 上,代表为零。不知道为什么会这样。一定是popping改变了contentOffset,但我不确定如何或为什么。 我想取消委托是一个很好的解决方案......看到对象无论如何都会被销毁。 【参考方案1】:似乎解决问题的唯一方法就是我已经完成的操作...在动画之前将代理设置为 nil。
self.collectionView.delegate = nil;
希望这对将来的其他人有所帮助。
【讨论】:
我在 -(void)dealloc 方法中添加了它。 @md_develop 这是放置它的最佳位置 我刚刚用 UITableView 发生了这种情况。我不知道为什么,但是将委托设置为 nil 修复了它。但是,出于某种原因,这感觉就像是 hack。 @Johnny 我会说这是一个 hack。我看不出这种行为的原因,直到 Apple 修复它(我认为这永远不会发生),这似乎是最好的选择。 @SodbilegGansukh 所有证据都表明这是一个错误,因为我从来没有将代表设置为 nil 来处理其他任何事情。我不知道它是否已修复,从持续的兴趣来看,它可能不是......【参考方案2】:在您的视图控制器中设置self.automaticallyAdjustsScrollViewInsets = NO;
。
我遇到了类似的问题,发现在离开页面时,contentOffset
每次都会更改 20。
我发现在我的视图控制器中设置这个属性停止了这种变化,因此不再调用scrollViewDidScroll
。结果是视图控制器会自动调整内容插入以适应状态栏、导航栏等的变化。即使您离开。
我认为这是一个更好的解决方案,并且可以正确解释为什么调用滚动方法。
【讨论】:
对我来说,self.automaticallyAdjustsScrollViewInsets = NO;
导致了崩溃。将其设置回YES
,即可解决问题。这很奇怪。【参考方案3】:
你可以在你的控制器中试试这个。
[self setEdgesForExtendedLayout:UIRectEdgeNone];
希望这会对你有所帮助。
【讨论】:
以上是关于UICollectionView 调用 scrollViewDidScroll:从导航堆栈中弹出时的主要内容,如果未能解决你的问题,请参考以下文章
调用 didHighlightItemAtIndexPath 而不调用 UICollectionView 的 didSelectItemAtIndexPath
未调用 UIcollectionView 的 didDeselectItemAt 但调用了 didSelectItemAt?
在 sizeForItemAtIndexPath 中调用 UICollectionView 单元
重新加载和调用requestImageForAsset时UICollectionView闪烁