zoukankan      html  css  js  c++  java
  • ios UICollectionView reloadData无法更新的奇怪问题。

    报错    Assertion failure in -[UICollectionViewData invalidateItemsAtIndexPaths:]

    近来偶尔用到UICollectionView,对于九宫格之类的布局还是很方便的。但使用过程中却出现一个奇怪的问题,暂时没时间仔细研究。先记录。

    在UICollectionViewCell中定义一个图标和一个文本,显示的效果是典型的九宫格。默认会有几条数据,点击最后一个cell会弹出编辑框添加自定义的cell。使用过程中出现的问题时,在第二行最后一个添加的自定义cell,图标怎么都改变不了。如果将整个view切换一下,显示又变成正常了。如下图:

    查看打印出来的数据,是正常的。如下:

    (
    {
        index = 0;
        name = "U5915U9633";
        thumb = "sunset_btn_nor";
    },
    {
        index = 1;
        name = "U665aU9910";
        thumb = "dinner_btn_nor";
    },
    {
        index = 2;
        name = "U770bU7535U89c6";
        thumb = "tv_btn_nor";
    },
    {
        index = 3;
        name = "U6e29U548c";
        thumb = "soft_btn_nor";
    },
    {
        index = 4;
        name = "U51b7U5149";
        thumb = "coldlight_btn_nor";
    },
    {
        index = 5;
        name = night;
        thumb = "my_btn_nor";
    },
    {
        index = 6;
        name = morning;
        thumb = "my_btn_nor";
    },
    {
        index = 7;
        name = sunset;
        thumb = "my_btn_nor";
    },
    {
        index = 8;
        name = "U81eaU5b9aU4e49";
        thumb = "add_btn_nor";
    }
    )

    添加断点,发现数据也没有问题。代码的处理方式是在插入或者更新数据后,调用

     

    [collectionView reloadData];

    的方法。

    网上搜索,也看到有人问类似的问题。有些人给出的解决办法是加一个空的UIView在上面,强制整个collection view刷新。但感觉不是好的办法。

    后来试了更新指定项,问题就不出现了。

    以下两种方法均有效:

    [self.collectionViewreloadItemsAtIndexPaths:@[[NSIndexPathindexPathForRow:7inSection:0]]];

    或者

    [self.collectionViewreloadSections:[NSIndexSetindexSetWithIndex:0]];

    至于为什么reloadData会无效。这个暂时留下,等有空的时候再研究一下其原理。或者有牛人知道也请不吝赐教。

    另外,这情况也提醒我们,能确定加载某个子项的,还是调用直接刷新指定项更好。一来效率高,二来避免出现莫名其妙的现象。

    ==================


    昨天的问题补充一下。发现不是reloadData的问题。后来在测试中,使用reloadSections也会出现问题。
    跟踪了一下,发现在reloadData过程中,最后一个(也就是新增加)的一个cell没有调用layoutSubviews。因为是在layoutSubviews中改变custom cell的image和label的值,所以新增加的cell没有刷新。后来换成了在赋值过程中调用更新image和label的代码,这样无论reloadData和reloadSections都有效了,因为这样保证了加载数据的时候imageView和label都被调用。或者也可以在cellForRowAtIndexPath中调用[cell setNeedsLayout];去强制调用layoutSubviews,这样也达到更新的效果。
    但是有点比较奇怪的是,之前的uitableview和uicollectionview自定义cell都是在layoutSubviews里面更新对应的控件,却没出现过问题。是不是iOS7以后,加载的机制发生变化了。这个有待进一步研究。
    今天查找资料的时候,顺便收集了一个图表,图表清楚说明了会引起调用layoutSubviews的操作。(x表示被调用)

  • 相关阅读:
    mysql 数据库集群连接配置
    tomcat server.xml 配置优化
    使用PowerDesigner16.5 逆向数据库生产表结构或导出word文档
    SpringBoot、thymeleaf 国际化配置
    解决 SpringBoot 跨域请求问题
    在 centos7 系统中用 docker 创建 tomcat 服务镜像
    JAVA 调用 com.google.protobuf
    登录后获取token,作为参数传入下一个操作
    通过二进制数据流方式上传图片及性能测试脚本编写
    信息服务(ISS)管理器之报错【"/"应用程序中的服务器错误。】
  • 原文地址:https://www.cnblogs.com/shenlaiyaoshi/p/9459863.html
Copyright © 2011-2022 走看看