UITableView:下拉刷新和上拉加载更多

【转载请注明出处】

本文将说明具有多个section的UITableView在使用下拉刷新机制时会遇到的问题及其解决方案。

工程地址在帖子最下方,只需要代码的直拉到底即可。

【目录】

1、现象分析;

2、解决方案;

3、工程地址。

1、现象分析 
当前的大多数支持下拉刷新的库,都是通过修改UIScrollView的contentInset实现的。

(可参见我的这篇帖子:UITableView:下拉刷新和上拉加载更多

使用这种方法带来的问题是,当UITableView具有多个section时,依照上述方式使用下拉刷新,在加载过程中上滑,会出现样式跑版:

为了分析出问题所在,首先在控制台打印出正常状态下UITableView的所有子View :

比较各行的frame.origin.y可以看出,UITableView的section headerView是和cell一起,按顺序放入基类UIScrollView的内容View中的。

再看加载中时的情况:

从Pull2RefreshView的frame可以看出,此时UITableView的contentInset已经被修改为(65, 0, 0, 0)。而section headerView和各个cell的frame.origin.y不受影响,和预期一致。

最后看看在加载中状态下上滑时的情况,将UITableView上滑至上方图中所示情境,即第一行的cell刚刚好越过section headerView:

可以看到,section headerView的frame.origin.y发生了变化,它和第二个cell一起被放在了第一个cell的下方,即:

section headerView.frame.origin.y == firstCell.frame.origin.y + cellHeight;

继续上滑,可以看到section headerView.frame.origin.y不断变化,但在界面显示上,始终位于距离UITableView.frame.origin.y为65(即修改后contengInset.top的值)的位置,直到下一个section headerView出现时,才随着cell向上移动,如图:

注意:不论在任何情况下,第一个cell的frame.origin.y始终为section headerView的高度,在本例中为23,即使它已经处于section headerView的上方】

2、解决方案 

由此,可以粗略得出以下结论:

A、 section headerView和cell之间并不是简单的顺序摆放的关系,它们之间可以发生重叠;

B、 section headerView在界面上的显示位置由UITableView.contentInset.top决定,直到被下一个section headerView替代。

如此,想要在滑动时修改section headerView的显示位置,令其和cell一起移动,只需要动态地修改UITableView.contentInset.top即可,如下:

 1  - (void)scrollViewDidScroll:(UIScrollView *)scrollView
 2   {
 3       //added 2013.11.28 动态修改headerView的位置
 4       if (headerRefreshing)
 5       {
 6           if (scrollView.contentOffset.y >= -scrollView.contentInset.top
 7               && scrollView.contentOffset.y < )
 8           {
 9               //注意:修改scrollView.contentInset时,若使当前界面显示位置发生变化,会触发scrollViewDidScroll:,从而导致死循环。
              //因此此处scrollView.contentInset.top必须为-scrollView.contentOffset.y
              scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, , , );
          }
          else if (scrollView.contentOffset.y == )//到0说明headerView已经在tableView最上方,不需要再修改了
          {
              scrollView.contentInset = UIEdgeInsetsZero;
          }
      }
      
      //other code here...
  }

Added 2014.7.24:

对于不需要提交到AppStore的应用,还有一个更简单的办法,即覆盖UITableView的私有方法。

- (BOOL)allowsHeaderViewsToFloat
{
return NO;
} - (BOOL)allowsFooterViewsToFloat
{
return NO;
}

3、工程地址

使用iOS 6.1 SDK编译,使用ARC。
地址:https://github.com/cDigger/CDPullToRefreshDemo

【参考】

1、Section Headers in UITableView when inset of tableview is changed

http://stackoverflow.com/questions/5466097/section-headers-in-uitableview-when-inset-of-tableview-is-changed

2、Change Default Scrolling Behavior of UITableView Section Header

http://stackoverflow.com/questions/664781/change-default-scrolling-behavior-of-uitableview-section-header

下拉刷新和UITableView的section headerView冲突的原因分析与解决方案的更多相关文章

  1. UITableView:下拉刷新和上拉加载更多

    [转载请注明出处] 本文将说明让UIScrollView支持"下拉刷新"和"上拉加载更多"的实现机制,并实现一个可用的tableView子类,以下主要以&quo ...

  2. IOS学习笔记34—EGOTableViewPullRefresh实现下拉刷新

    移动应用开发中有这么一种场景,就是在列表中显示的数据刷新,有点击刷新按钮刷新的,也有现在最流行的由Twitter首先推出的下拉刷新功能,在IOS中,使用下拉刷新更新UITableView中的数据也用的 ...

  3. listview下拉刷新和上拉加载更多的多种实现方案

    listview经常结合下来刷新和上拉加载更多使用,本文总结了三种常用到的方案分别作出说明. 方案一:添加头布局和脚布局        android系统为listview提供了addfootview ...

  4. ListView装上拉电阻下拉刷新

    主要用到了这个几个文件.MainActivity是界面的Activity,MyAdapter是ListView的自己定义适配,MyListView是自己定义带头部LIistView,假设仅仅须要上拉载 ...

  5. 【转载】Android中ListView下拉刷新的实现

    在网上看到一个下拉刷新的例子,很的很棒,转载和更多的人分享学习 原文:http://blog.csdn.net/loongggdroid/article/details/9385535 ListVie ...

  6. Android中ListView下拉刷新的实现

    ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: packa ...

  7. ListView下拉刷新上拉加载更多实现

    这篇文章将带大家了解listview下拉刷新和上拉加载更多的实现过程,先看效果(注:图片中listview中的阴影可以加上属性android:fadingEdge="none"去掉 ...

  8. UITableView与UISearchController搜索及上拉加载,下拉刷新

    #import "ViewController.h" #import "TuanGouModel.h" #import "TuanGouTableVi ...

  9. IOS UITableView下拉刷新和上拉加载功能的实现

    在IOS开发中UITableView是非常常用的一个功能,而在使用UITableView的时候我们经常要用到下拉刷新和上拉加载的功能,今天花时间实现了简单的UITableView的下拉刷新和上拉加载功 ...

随机推荐

  1. 使用 python 管理 mysql 开发工具箱 - 2

    这篇博文接着上篇文章<使用 python 管理 mysql 开发工具箱 - 1>,继续写下自己学习 python 管理 MySQL 中的知识记录. 一.MySQL 的读写分离 学习完 My ...

  2. beta阶段——项目复审

    beta阶段--项目复审 小组的名字和链接 优点 缺点 bug 排名顺序 颜罗王team http://www.cnblogs.com/LDLYMteam 界面清新,音乐能够选择是否播放,词汇按照四六 ...

  3. 结对编程——paperOne基于java web的简易四则运算出题网站

    项目成员:张金生     张政 需求分析: 1.要进行四则运算: 2.运算题目随机: 3.进行对错判断: 4.整数运算. 程序概要: 1.用JSP实现: 2.用户可选择题目数量: 3.答题页用表格列出 ...

  4. linux 转移mysql文件操作流程

    1.现将mysql停服 2.将文件拷贝到指定目录cp ./sales_trade_2.ibd /db/data/mysql/data_warehouse/sales_trade_2.ibd 3.检查新 ...

  5. 微信Web开发者工具-下载、安装和使用图解

    开发和测试小程序,需要借助微信官方提供的微信Web开发者工具进行预览和调试代码,从下载安装到使用,大致的流程如下: 1.下载安装包 下载地址传送门:https://developers.weixin. ...

  6. dbgrid多选日记

    procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char); begin then begin DBGrid1.DataSourc ...

  7. SQL Server bit数据类型

    bit值保存为1/0,1代表true,0代表false读取数据库数据时,可以直接用bool型读取该字段,会直接转换为true/false 数据库表结构 CREATE TABLE [dbo].[BitT ...

  8. 第139天:详解cookie、 sessionStorage 和localStorage

    1.cookie:存储在用户本地终端上的数据.有时也用cookies,指某些网站为了辨别用户身份,进行session跟踪而存储在本地终端上的数据,通常经过加密.一般应用最典型的案列就是判断注册用户是否 ...

  9. @Retention(保留) 此注解用于运行时候(反射)时候使用 如果不使用的话 在反射时候无法获取到注解的值

    @Retention(保留) 此注解用于运行时候(反射)时候使用 如果不使用的话 在反射时候无法获取到注解的值

  10. Authenticator及AuthenticationStrategy

    Authenticator的职责是验证用户帐号,是Shiro API中身份验证核心的入口点: 如果验证成功,将返回AuthenticationInfo 验证信息:此信息中包含了身份及凭证:如果验证失败 ...