Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 614|回复: 0

【已解决】iOS11使用MJRefresh上拉加载结束tableView闪动、跳动的问题

[复制链接]
  • TA的每日心情
    奋斗
    昨天 12:41
  • 签到天数: 780 天

    [LV.10]以坛为家III

    2047

    主题

    2105

    帖子

    71万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    715808
    发表于 2021-6-25 05:07:35 | 显示全部楼层 |阅读模式

    更新提示:

    【2018年11月20日更新】

    经过放置在项目中运行发现,如果在快速滚动tableview的时候会在下面这行代码中崩溃(慢慢的滚动是没关系的~):

    CGFloat cellHeight = [tableView rectForRowAtIndexPath:[NSIndexPath
    indexPathForRow:(indexPath.row - 1) inSection:indexPath.section]].size.height;

    提示的error原因是,超出数组的范围进行访问。原因,后面有时间会详细说明更新进来,大致的原因就是利用rectForRowIndexPath方法去取cell的时候,从展示在界面上的第一个完整的cell开始作为下标为0的cell。比如,一个界面中可以存放4个cell,第5个cell将要展示的时候,会在界面中去取下标为3的cell。有一点需要插播一条,就是在第5个cell还没有漏出来之前,系统就会去调用tableview的cellForRowAtIndexPath协议方法了,这就是为什么你慢慢的滚动tableview是没有关系的。如果快速滚动的话,虽然系统也是在第5个cell还没有漏出来之前就去调用那个协议方法了,但是等到运行到rectForRowIndexPath方法的时候,第1个cell就已经被顶出tableview的可视区域了,这个时候下标为0的cell就是从开始的第2个cell开始了(第一个cell在屏幕中的部分并不是完整的了),所以就会抛出异常。

    暂时先把“indexPath.row - 1”的“-1”改为“-2”暂且应付

    因为如果tableview的可视范围最多只能同时容纳2个完整的cell的话,使用“-2”就会往前超域访问数组;如果最多只能同时容纳1个完整的cell的话,使用“-1”也会往前超域访问数组;如果连一个完整的cell都容纳不下,那么这个方法就根本行不通了。(很尴尬~)


     

    问题背景:

    使用MJRefresh一直都很方便,适配到iOS11以后,tableView上拉加载更多数据动画结束后,出现tableView跳动、闪动的现象。

    通过浏览Github上的MJRefresh的Issues后发现,很多人都遇到了这个问题。而且,一般遇到这个问题的都是使用自动化布局来自动约束Cell高度的同学。如果将Cell是通过tableView的rowHeight属性或者对应的协议方法给定的,就不出遇上这个问题。

         

    分析问题:

    为了实现Cell的高度自适应,需要做三步:

    1、不要设置rowHeight、不要重写设置rowHeight的协议方法

    2、在搭建Cell的UI时,让最后一个控件的bottom等于cell.contentView.mas_bottom(这里用masonry举例)

    3、设置tableView的下面两个属性:

    self.estimatedRowHeight = 44;
    self.rowHeight = UITableViewAutomaticDimension;

    有同学说,走回以前“根据内容计算好cell的高度”的方式,很定是不合适的,与苹果推崇的AutoLayout相违背。

    所以使用上面的高度自适应方式,是没错的,错就错在

    estimatedRowHeight

    这个属性的设置。

    如果通过高度自适应计算出来Cell的真实高度与给出的估算高度相差太大,很定出现view渲染过程的异常。

    解决方式:

    根据上面的分析,本ID采用的方式是加载cell时,将上一个cell对象的高度设置为下一个即将出现的cell的预估高度。

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
    *)indexPath {
    if (indexPath.row > 1) { CGFloat cellHeight = [tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:(indexPath.row - 1) inSection:indexPath.section]].size.height; self.estimatedRowHeight = cellHeight; } //。。。你之前的代码 return cell; }

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-8-21 12:57 , Processed in 0.061787 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表