转载请保留地址wossoneri.com

问题

首先看一下我之前写的demo:link

demo是封装了一个控件,直接在MainViewControllerviewWillAppear里初始化,并且调用一个初始化滚动到中间的方法,方法主要是调用了

- (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的更多相关文章

  1. iOS UICollectionView 在滚动时停在某个item位置上

    方法一:实现UIScrollView的代理,然后实现下面这个方法 #pragma mark - UIScrollViewDelegate//预计出大概位置,经过精确定位获得准备位置- (void)sc ...

  2. [iOS] UICollectionView实现图片水平滚动

    最新更新: 简单封装了一下代码,参考新文章:UICollectionView实现图片水平滚动 先简单看一下效果: 新博客:http://wossoneri.github.io 准备数据 首先先加入一些 ...

  3. iOS无限循环滚动scrollview

    经常有园友会问"博主,有没有图片无限滚动的Demo呀?", 正儿八经的图片滚动的Demo我这儿还真没有,今天呢就封装一个可以在项目中直接使用的图片轮播.没看过其他iOS图片无限轮播 ...

  4. iOS关于菜单滚动视图实现

    菜单滚动视图也是在项目开发过程中比较常用到的功能,先直接看效果图 实现的效果如下: 当菜单个数的总长度超过一个屏宽度就计算每一个的文字宽度,若没有则只进行一个屏平分,点击菜单项时,滚动的视图位置会随着 ...

  5. Android RecyclerView 滚动到中间位置

    最近看到QQ音乐的歌词每次滑动后都可以滚回到中间位置.觉得甚是神奇,打开开发者模式显示布局,发现歌词部分不是采用 android 控件的写的,应该是前端写的.于是,我想,能不能用 recyclerVi ...

  6. UITableViewCell上放UICollectionView ,UICollectionViewCell无法复用bug

    如题: UITableViewCell上放UICollectionView ,UICollectionViewCell无法复用bug 如果UITableViewCell的size大于整个collect ...

  7. 处理ios的overflow滚动bug

    先说说这个bug的场景 .container{ height:100vh; overflow-y:scroll; } 没毛病,总有这种类似的情况,需要在容器内滚动,但是!这种容器内的滚动在ios上面处 ...

  8. iOS UICollectionView之二(垂直滚动)

    #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...

  9. iOS UICollectionView之-(水平滚动)

    #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...

随机推荐

  1. TensorFlow.js之安装与核心概念

    TensorFlow.js是通过WebGL加速.基于浏览器的机器学习js框架.通过tensorflow.js,我们可以在浏览器中开发机器学习.运行现有的模型或者重新训练现有的模型. 一.安装     ...

  2. CentOS 7 安装配置 Gitlab

    centos:http://www.centos.org/download/ download:https://about.gitlab.com/downloads/ update:https://g ...

  3. 滚动条事件window.onscroll

    例:统战滚动条位置随高度变化 // 答题卡位置随滚动条变化 window.onscroll = function(){ var a = document.documentElement.scrollT ...

  4. 全网最全的Windows下Python2 / Python3里正确下载安装用来向微信好友发送消息的itchat库(图文详解)

    不多说,直接上干货! 建议,你用Anaconda2或Anaconda3. 见 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装用来向微信好友发送消息的itchat库( ...

  5. 全网最详细的Cloudera Hue执行./build/env/bin/supervisor 时出现KeyError: "Couldn't get user id for user hue"的解决办法(图文详解)

    不多说,直接上干货! 问题详情 如下: [root@bigdata-pro01 hue--cdh5.12.1]# ./build/env/bin/supervisor Traceback (most ...

  6. Tomcat学习总结(13)—— Tomcat常用参数配置说明

    1.修改端口号 Tomcat端口配置在server.xml文件的Connector标签中,默认为8080,可根据实际情况修改. 修改端口号 2.解决URL中文参数乱码 在server.xml文件的Co ...

  7. Java 使用gson 解析 Json

    json数据 { "resultcode": "200", "reason": "successed!", " ...

  8. Linux 下面解压.tar.gz 和.gz文件解压的方式

    Linux 下面解压.tar.gz 和.gz文件解压的方式 两种解压方式 1 .tar.gz 使用tar命令进行解压 tar -zxvf java.tar.gz 解压到指定的文件夹 tar -zxvf ...

  9. POJ 1679 The Unique MST(判断最小生成树是否唯一)

    题目链接: http://poj.org/problem?id=1679 Description Given a connected undirected graph, tell if its min ...

  10. Trace & Error log in file

    1. Log机制 做一些大型项目的时候,对代码的调试最有效的办法往往是最直接.最简单的log机制: 即对可以出设置打印店,对应打印信息进行调试(当然是有gdb也许你会觉得很高大上,但是实际项目中,gd ...