[iOS] UICollectionView初始化滚动到中间的bug
转载请保留地址wossoneri.com
问题
首先看一下我之前写的demo:link
demo是封装了一个控件,直接在MainViewController的viewWillAppear里初始化,并且调用一个初始化滚动到中间的方法,方法主要是调用了
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated;
方法,在初始化后将其滚动到中间的区域。不过,当我在项目里使用的时候,遇到了调用该方法却无法滚动到中间的情况。
我的使用步骤是:在我界面的UIView中,创建该控件对象并且调用滚动到中间的方法。
scrollToItemAtIndexPath使用
发现效果无法实现,我第一时间检查了函数有没有调用,然后发现是调用的了,但没有出现该出现的效果。所以简单看一下该方法的官方注释。xcode提示的描述是:
Scrolls the collection view contents until the specified item is visible.只是方法的作用,并没有说使用条件。为了快速解决问题,google了一下scrolltoitematindexpath not working,在这里:link找到了答案:
不知道这是一个bug还是一个特性,每当在
UICollectionView显示它的subview之前调用scrollToItemAtIndexPath:atScrollPosition:Animated方法,UIKit就会报错。
所以要解决它,就应该在viewController中,在你能确认CollectionView完全计算出其subview布局的地方去调用这个方法。比如在viewDidLayoutSubviews里调用就没有问题。
方法的意思已经明确,就是找到一个能计算出collectionview的所有布局地方调用滚动方法。但我的界面使用的是自动布局,只在模块外有一个viewController,其余的都是在UIView中创建添加,所以在我使用这个控件对象的地方,我无法复写viewController的方法。所以想了几个办法。
-layoutsubviews
既然情况发生在UIView中,那首先想到的是重写该方法。重写之前,看一下文档说明:
Lays out subviews.
Discussion
The default implementation of this method does nothing on iOS 5.1 and earlier. Otherwise, the default implementation uses any constraints you have set to determine the size and position of any subviews.
Subclasses can override this method as needed to perform more precise layout of their subviews. You should override this method only if the autoresizing and constraint-based behaviors of the subviews do not offer the behavior you want. You can use your implementation to set the frame rectangles of your subviews directly.
You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method.
该方法为子view布局。
子类可以复写该方法为子view实现更精确的布局。但你只应该在用自动布局时无法实现效果时用它。而且你不应该直接调用该方法,如果需要强制刷新布局,调用setNeedLayout,会在下一次绘制刷新前更新布局。调用layoutIfNeed可以立即刷新布局。
看起来这个方法有用,我便试了一下。
[self setNeedLayout];
[self layoutIfNeed];
[myPicker scrollToCenter];
然而还是没有效果。
view.window
前面的方法没效果,我又想了一下scrolltoitematindexpath的实现条件,是在UICollectionView显示之后调用才有效,所以我需要在UIView中获得它显示的状态再去滚动。幸好,我的控件也是继承UIView的,其中有这么一个属性:
Property: window
This property is nil if the view has not yet been added to a window.
也就是说这个属性值代表着这个view有没有放在窗口中显示,那么我就需要在当前UIView的生命周期中检查myPicker对象的这个属性就好了。所以最后的解决方法是,起一个子线程,对myPicker的状态进行检查,当状态为显示的时候调用滚动方法:
NSThread *checkShownThread;
checkShownThread = [[NSThread alloc] initWithTarget:self selector:@selector(checkIfViewIsShowing) object:nil];
[checkShownThread start];
- (void)checkIfViewIsShowing {
while (1) {
if (hPicker.window != nil) {
break;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[hPicker scrollToCenter];
});
[checkShownThread cancel];
checkShownThread = nil;
}
小结
这个bug只是一个很小的bug,我记录它的原因,一方面是解决过程中学习到了一些不了解的方法,另一方面是记录一下解决问题的思路,希望可以对以后的学习有帮助。也希望将来回头看这一段的时候可以对问题有更好的解决思路。
[iOS] UICollectionView初始化滚动到中间的bug的更多相关文章
- iOS UICollectionView 在滚动时停在某个item位置上
方法一:实现UIScrollView的代理,然后实现下面这个方法 #pragma mark - UIScrollViewDelegate//预计出大概位置,经过精确定位获得准备位置- (void)sc ...
- [iOS] UICollectionView实现图片水平滚动
最新更新: 简单封装了一下代码,参考新文章:UICollectionView实现图片水平滚动 先简单看一下效果: 新博客:http://wossoneri.github.io 准备数据 首先先加入一些 ...
- iOS无限循环滚动scrollview
经常有园友会问"博主,有没有图片无限滚动的Demo呀?", 正儿八经的图片滚动的Demo我这儿还真没有,今天呢就封装一个可以在项目中直接使用的图片轮播.没看过其他iOS图片无限轮播 ...
- iOS关于菜单滚动视图实现
菜单滚动视图也是在项目开发过程中比较常用到的功能,先直接看效果图 实现的效果如下: 当菜单个数的总长度超过一个屏宽度就计算每一个的文字宽度,若没有则只进行一个屏平分,点击菜单项时,滚动的视图位置会随着 ...
- Android RecyclerView 滚动到中间位置
最近看到QQ音乐的歌词每次滑动后都可以滚回到中间位置.觉得甚是神奇,打开开发者模式显示布局,发现歌词部分不是采用 android 控件的写的,应该是前端写的.于是,我想,能不能用 recyclerVi ...
- UITableViewCell上放UICollectionView ,UICollectionViewCell无法复用bug
如题: UITableViewCell上放UICollectionView ,UICollectionViewCell无法复用bug 如果UITableViewCell的size大于整个collect ...
- 处理ios的overflow滚动bug
先说说这个bug的场景 .container{ height:100vh; overflow-y:scroll; } 没毛病,总有这种类似的情况,需要在容器内滚动,但是!这种容器内的滚动在ios上面处 ...
- iOS UICollectionView之二(垂直滚动)
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...
- iOS UICollectionView之-(水平滚动)
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...
随机推荐
- Bash控制结构
1. if-else语句 #!/bin/bash #if ... fi 语句: if [ $a != $b ] then echo "a != b" fi #if ... else ...
- Intellij IDEA 编译等级与源代码等级不一致问题
错误:Error:java: javacTask: source release 1.7 requires target release 1.7 原因:生成class字节码的java版本,低于了源代码 ...
- 推荐一个 MYSQL 的命令行的客户端 MYCLI
MYCLI 是一个 MySQL 命令行客户端工具 , 可以实现自动补全(auto-completion)和语法高亮,平时测试环境维护一些数据还是蛮方便的. https://github.com/dbc ...
- 【转】谷歌三大核心技术(三)Google BigTable中文版
谷歌三大核心技术(三)Google BigTable中文版 摘要 Bigtable 是一个分布式的结构化数据存储系统,它被设计用来处理海量数据:通常是分布在数千台普通服务器上的PB级的数据.Goo ...
- 导入maven项目遇到中文乱码
windows->preferences->content types->word Document 并输入utf-8->update; 右键选中的项目,选择propertie ...
- Java设计模式学习记录-策略模式
策略模式 策略模式的定义是:定义了一系列的算法,把它们一个个的封装起来,并且使它们可相互替换,让算法可以独立于使用它的客户而变化. 设计原则是:把一个类中经常改变或者将来可能会经常改变的部分提取出来作 ...
- CTSC 2018 游记
day0 李总提前一天放假,回家颓整理行李... 然而我... 早上:睡觉... 中午:睡觉... 晚上:睡觉去火车站... 吃了几把鸡,本来想带李总入坑,但他挥手拒绝然后被李总带进了炸金花的坑... ...
- WinForm中遇到Label要显示的内容太长,自动换行
很多朋友都会在开发WinForm中遇到Label要显示的内容太长,但却不能换行的问题.这里我总结了几种方法,供大家参考. 第一种是把Label的AutoSize属性设为False,手动修改Label的 ...
- vue-cli中配置屏幕自适应(px2rem)
在vue-cli中配置屏幕自适应的方法 首先,我们需要安装flexible库. npm i lib-flexible --save 在index.html文件当中配置meta标签, <meta ...
- [Redis] redis在centos下安装测试
下载软件,使用命令wget xxx,参数:url 例如: wget http://download.redis.io/releases/redis-3.0.0.tar.gz 解压缩,使用命令tar,参 ...