本文提供了需求所描述问题的解决方案,但是关于滑动CollectionView时KVO监听ContentSize会不断触发回调的问题依然困扰着我

先抛出我的疑惑:

KVO监听UICollectionView的ContentSize,可是为hen么滑动CollectionView这个操作会使观察者监听到contentSize的变化呢?现实对我的认知造成了冲击

在我的理解中,在DataSource没有数据源变化的情况下,CollectionView的ContentSize渲染结束后应该是确定了的(当然CollectionView在滑动过程中对item本身就存在着不断地渲染,我提到的渲染。。。你懂的,就是整体上的,在我理解哈),所以!CollectionView在滑动时不应该触发KVO的监听呀。 很有道理对不对?但事实不是这样的sad☹️ 现实是:滑动CollectionView会使KVO疯狂调用监听ContentSize的回调

接下来阐述一下心路历程吧

需求描述:

产品同学期望在拍摄新的照片后能够横向滑动到新增的照片,让用户感知到照片拍摄成功。如图:

实现思路:

如需滚动到新增照片(即CollectionView的底部)需要照片在CollectionView上完成渲染操作,我自yan而yan的就想到了KVO,去监测CollectionView的ContentSize,当新增照片成功渲染到CollectionView上后ContentSize势必会改变,这时我修改ContentOffset去完成自动滑动。 初版实现代码如下:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {if([keyPath isEqualToString:@"contentSize"]) {if (context == photosCollectionViewContext) {      // 此处context为自定义标识符,客官不必纠结其意义CGFloat offset = MAX(self.photosCollectionView.contentSize.width - self.photosCollectionView.frame.size.width, 0.0);[self.photosCollectionView setContentOffset:CGPointMake(offset, 0) animated:YES];}}
}
复制代码

遇到的问题:

当我对展示照片的CollectionView做横向滑动时(照片数量多于4张),KVO竟然监测到CollectionView.ContentSize变化,不断回调其 - observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context 方法,导致CollectionView滑动卡顿且最终永远停在照片尾部(即底部)。

解决方法:

我们在创建观察者的时候通过增加 NSKeyValueObservingOptionNew NSKeyValueObservingOptionOld参数将变化后的新值旧值告诉我们:

[self.photosCollectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:photosCollectionViewContext];
复制代码

通知会调用 - observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context 方法,我们利用 change 中的数据newold进行逻辑上的判断,控制CollectionView产生我们所需要的滑动。 解决:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {if (context == photosCollectionViewContext) {NSValue *newSizeValue = change[@"new"];NSValue *oldSizeValue = change[@"old"];CGSize newSize = [newSizeValue CGSizeValue];CGSize oldSize = [oldSizeValue CGSizeValue];// 判断条件:若新值与旧值相等即ContentSize没有发生变化则忽略新值contentSize.width > 旧值content.size即新增图片导致的contentSize增大才处理滑动if (![newSizeValue isEqualToValue:oldSizeValue] && newSize.width > oldSize.width) {CGFloat offset = MAX(self.photosCollectionView.contentSize.width - self.photosCollectionView.frame.size.width, 0.0);[self.photosCollectionView setContentOffset:CGPointMake(offset, 0) animated:YES];}}}
}
复制代码

这样就可以满足需求了。

But!!!!!!有一个问题却不断困扰着我就是文章开头提到的滑动操作为什么会触发KVO?

出于好奇,我在解决方法中的这段代码上打了断点,滑动CollectionView观察每次newSizeoldSize的数值,发现在滑动中newSizeoldSize的值始终是完全一致的,此处是印证了我开头所说的 在DataSource没有数据源变化的情况下,CollectionView的ContentSize渲染结束后应该是确定了的

这个说法。这就让我对KVO的触发机制产生了疑问,对KVO来说:

KVO的监听从对应key-path的属性是否调用了- ()set方法,即使UICollectionViewContentSize的值没有变化,但是滑动中UICollectionView.contentSize- ()set方法被调用了,KVO的检测到并回调,后续空了重写一下了解一下UICollectionView.contentSize相关内容再做补充。

【开发问题记录①】关于滑动CollectionView时ContentSize变化的问题相关推荐

  1. IOS开发 当滑动tabelview时,使键盘滑落

    //滑动tabelView 使键盘滑落 -(void)scrollViewDidScroll:(UIScrollView *)scrollView {[[UIApplication sharedApp ...

  2. IOS塔防游戏《坦克对大炮》的开发设计记录

    IOS塔防游戏<坦克对大炮>的开发设计记录 引子 游戏已经在App Store上线几个月了,一直很想写点什么记录一下.真要写的时候,却又发现无从下笔没啥好写的.在2012年进入IOS,对于 ...

  3. Android 开发学习记录(4)---- httpclient使用(三)

    之前在Android 开发学习记录(3)---- httpclient使用(二)中介绍了如何使用httpclient访问需要账户登录的网址,当然首先是要有一个合法的登录账户. 但是现在好多网站在登录时 ...

  4. python 鼠标轨迹录制_python记录鼠标滑动轨迹

    一个记录鼠标轨迹的程序. 一直需要一个记录鼠标轨迹的程序,本想找一个,但是都不太合适,所以就自己写了一个.功能很简单,就是记录鼠标按下时的滑动轨迹. from pynput import mouse ...

  5. 解密网游木马开发全记录(一)

    解密网游木马开发全记录 ------WM_GETTEXT篇 网络虚拟财产的安全越来越受到广大网民的关注,而黑客经常使用非法手段获取网游账号及密码进行非法盈利.为了揭露网游盗号的基本原理,我将给大家演示 ...

  6. 微信小游戏开发学习记录2

    接上一篇:微信小游戏开发学习记录_寂静流年韶华舞的博客-CSDN博客_微信小游戏开发学习 目录 一.UI系统 1.基础渲染组件-精灵组件 (1)操作: (2)Sprite 属性 (3)渲染模式 2.L ...

  7. Android Studio 项目设计开发bug记录以及未来新技术

    文章目录 项目设计开发bug记录: (1)打包时出错 (2)关闭项目自启动 (3)显示工具栏 (4)怎么导入jar包 (5)导入工程出现异常 (6)run项目出现异常: (7)修改包名 (8)导入项目 ...

  8. Windows11 Android开发相关记录(持续更新...)

    Windows11 Android开发相关记录(持续更新-) 本章节主要记录安装好Windos系统后开发环境搭建及其心得. 以及开发常用软件和相关配置. 以下属于个人做法,仅供参考: 文章目录 Win ...

  9. Jetson开发实战记录(一):Jetson家族的基本介绍

    Jetson开发实战记录(一):Jetson家族的基本介绍 一.Jetson家族 二.Jetson家族产品横向对比 1.Jeston Nano 2.Jetson Xavier 3.Jetson Xav ...

最新文章

  1. [转]Servlet3.1规范
  2. 量子计算基础知识-2019/11/12
  3. 河北师范大学C语言试题,2017年河北师范大学信息技术学院838C语言程序设计考研强化模拟题...
  4. django-python3-mysql问题
  5. ajax原理 博客,AJAX工作基本原理
  6. VTK:构造图用法实战
  7. mac php 超时,PHP---Mac上开启php错误提示
  8. Win32ASM学习[10]:传送指令
  9. log4j无厘头异常
  10. [转载] Java静态绑定与动态绑定
  11. with(nolock)解释
  12. 电工入门基础知识问答,入门电工学习宝典系列
  13. 贝叶斯派的概率图模型概述(总)
  14. VirtualBox Linux网络配置
  15. JAVA练习——蝴蝶效应
  16. 桌面文件不见了怎么办?3个详细教程
  17. 语音直播开发平台打造新娱乐社交模式
  18. Lambda表达式与Stream
  19. Hackintosh连接收藏
  20. mysql ndb_MySQL NDB Cluster概述

热门文章

  1. 查找子字符串----KMP算法深入剖析
  2. 处理Clob数据(转)关于oracle中大对象处理的一些方法和实例
  3. Shell命令-系统信息及显示之stat、du
  4. DotNET:LINQ对泛型(Generic)操作和泛型方法及属性
  5. 使用ionic2开发一个登录功能
  6. 菜鸟学Linux 第030篇笔记 yum使用,源码编译安装
  7. C++ 中宏的使用 --来自:http://blog.csdn.net/hgl868/article/details/7058906
  8. 一名计算机专业新生代农民工的五年求学之路,从“低谷”到“山峰”
  9. 什么是大数据分析平台
  10. 用折半查找法查找某一字符在字符串中的位置