iOS-UITableView你需要掌握的属性

背景

  • 在现今的开发中,UITableView和UICollectionView算是最最流行的控件了,基本上每一个应用内部都会多次使用到这类控件,它们统一都继承自UIScrollView
  • 平时我们都会用它们来展示数据,但是也有很多情况,比如页面上下拖动的时候导航栏透明度改变、一个工具栏在页面向上拖动到一定程度后悬浮到一个位置不动了、再比如简书的个人页面,头像在导航栏上,头像会随着页面的上下拖动变大变小、再比如上拉下拉刷新的实现、再比如点击状态栏,tabbleView如果不是在最顶部,那么它会立即滚动到页面最顶部等等等等,这些效果全部都是通过UIScrollView的一些属性实现的
  • 而且这类控件也算是我们开发中最基本的控件了,基本我们天天都需要和它们打交道,所以说,掌握它们的使用不仅仅是对我们最基本的要求,也可以让我们实现很多效果,但是这些都需要建立在对它们一些易混淆属性理解的基础之上
  • 本文将以UITableView为例说明下它的一些关键属性,并结合一些属性简单实现下拉刷新
  • 先来看下这篇文章最后结合相关属性讲解的一个小Demo效果
refresh.gif

知识点

1)contenSize -- 滚动视图内容的尺寸

  • 这个属性是CGSize类型的,它决定了你的滚动视图是否能滚动,能够滚动多远
  • 这个属性对于实现我们本文要讲解的下拉刷新是至关重要的,我们需要明确contenSize包含了tabbleview的什么内容,也就是什么内容才算是contenSize的一部分
  • 除了UITableviewCell属于contenSize的一部分之外,tabbleview的头部和尾部视图也算是它的contenSize的一部分
  • 如果设置了内边距,那么内边距是不算contenSize的一部分的
  • 如果给tabbleview添加子控件,这个子控件也不属于contenSize的一部分
  • 而且给scrollview内部子控件添加约束时,最头疼的其实就是这个contenSize,它的contenSize需要根据子控件的尺寸以及子控件与scrollview之间的间距计算
偏移量.png

2)contentOffset -- 偏移量

  • 是一个CGPoint类型的属性,一般而言,上下滑动,我们需要它的contentOffset.y,左右滑动我们需要它的contentOffset.x
  • 这是一个滚动视图最最基本的属性,也是最重要的属性,基本上,上述所有效果都是基于它来实现的
  • 当tabbleview是在一个导航条下面的话,那么系统会自动将tabbleview内容增加64的顶部内边距,因此它的偏移量y值默认是-64
  • 我们可以这样去理解它,以一个上下滚动的tabbleview为例,contentOffset.y = tabbleview的frame的左上角的y值 - tabbleview的内容的左上角的y值,而且这个坐标系以tabbleview的内容的左上角为坐标原点
坐标系.png

3)showsHorizontalScrollIndicatorshowsVerticalScrollIndicator

  • 是BOOL类型的,决定了是否隐藏水平或者垂直方法滚动条,之所以提及这2个属性是要说一个注意点,比如我们在使用scrollview时,如果我们需要遍历scrollview的子控件数组,我们就需要注意这2个控件,它也算scrollview的子控件

4)scrollsToTop

  • 一个BOOL类型的属性,可以控制点击状态栏,是否让不在顶部的滚动视图回到最顶部
  • 属性默认为YES,也就是系统默认帮我们实现了这个效果
  • 需要说明的是如果页面有2个及以上滚动视图的时候,你需要控制哪一个滚动视图支持scrollsToTop,哪些不支持

5)estimatedHeight --- 估算高度

  • 这里针对tabbleview说一下这个属性,因为tabbleview不需要我们自己计算contensize,所以默认情况下,tabbleview都是先调用heightForRow方法然后再去调用cellForRow方法,而且heightForRow会根据当前tabbleview有多少行就去调用多少次,无论是否cell当前被展示

  • 如果我们给了tabbleview一个估算高度,那么它可以减少heightForRow方法的调用频率,延迟计算目前不需要展示cell的高度,需要展示再去计算,这个也算是这个属性的优点

  • 它也是有一定缺点的,既然是估算高度,那我们给多少算合适的,其实给多给少都不太好,给少了,它调用heightForRow方法就会多,给少了,虽然调用heightForRow方法少,但是tabbleview计算它的contensize的误差就越大,明显效果就是滚动条的高度很奇怪(跳跃性很大),所以还是根据cell平均值给一个估算高度

6)cellForRowAtIndexPath和indexPathForSelectedRow

  • cellForRowAtIndexPath这个方法根据传入的indexPath可以获得显示在tableView上的某一行cell
  • indexPathForSelectedRow这个方法可以在系统没有传入indexPath的方法或者自定义的方法中,通过该方法获得被选中的cell的indexPath,可以得到section,row,也是非常实用的

利用偏移量简单实现一下下拉刷新(仿新浪微博)

  • 其实一开始说的那些效果实现起来都是不难的,主要是我们需要对这些基本且关键属性非常理解,知己知彼,百战不殆嘛
  • 下面的这些代码主要是关于下拉过程中,更新下拉刷新控件文字以及箭头状态的描述,关于发送网络请求,这里只是模拟一下发送,新添加的数据也是假数据
  • 关于下拉刷新控件是否作为tabbleview的头部视图,这个我是建议不要这样做的,因为头部视图一般最好是用来作为轮播器或者广告使用,我们一般最好把刷新控件使用addSubview的方法添加到tabbleview上面最好
下拉刷新.png
/**
 *  停止拖拽,需要在这个方法里面监听停止拖拽的时候偏移量,根据偏移量判断刷新控件是否完全显示,是的话进入刷新,不是的话直接返回
 */

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    // 如果正在刷新, 直接返回
    if (self.isHeaderRefreshing) return;

    // 当偏移量 <= offsetY时(注意正负值), 刷新控件就完全出现了
    CGFloat offsetY = - (self.tableView.contentInset.top + self.headerBtn.lb_height);
    [self.loadingView stopAnimating];
    self.headerBtn.imageView.hidden = NO;
    if (self.tableView.contentOffset.y <= offsetY) { // 刷新header完全出现了
        // 进入刷新状态
        [self headerBeginRefresh];
    }
}
  • 还需要在scrollViewDidScroll方法中实时根据偏移量控制下拉刷新控件文字以及箭头的状态,这个监控状态的代码这里不贴出来了,放在代码里面有,注释也是很详细的
  • 开始刷新方法实现
#pragma mark - 开始刷新
- (void)headerBeginRefresh
{
    //如果当前正在刷新,那么不往下继续执行
    if (self.isHeaderRefreshing) return;
    //否则,进入刷新状态
    self.headerRefreshing = YES;

    //显示菊花
    self.loadingView.alpha = 1.0;
    [self.loadingView startAnimating];

    [self.headerBtn setTitle:@"加载中..." forState:UIControlStateNormal];

    self.headerBtn.imageView.transform = CGAffineTransformIdentity;
    self.headerBtn.imageView.hidden = YES;

    // 显示加载中...,这个时候这个刷新控件是会自己悬浮在导航栏下面,不需要人为拽着不松手
    //这个效果,我们可以通过增大tabbleview的内边距来达到这个效果
    [UIView animateWithDuration:0.25f animations:^{

        //因为刷新控件的y值就是-50,它自己高度也是50,所以只需要让tabbleview内边距向下走50,那么刷新控件就会完全显示了
        UIEdgeInsets inset = self.tableView.contentInset;
        inset.top += self.headerBtn.lb_height;

        self.tableView.contentInset = inset;
    }];
    //由于是模拟发送网络请求,所以延迟1.5秒后再去加载数据
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        // 发送请求给服务器
        [self loadNewData];
    });
}

  • 结束刷新方法实现
#pragma mark - 结束刷新
- (void)headerEndRefresh
{
    self.headerRefreshing = NO;
    self.headerBtn.hidden = YES;

    // 减小内边距
    // 刷新已经停止,不需要刷新控件显示在用户能看到的范围,所以需要减少tabbleview的内边距
    [UIView animateWithDuration:0.25 animations:^{

        UIEdgeInsets inset = self.tableView.contentInset;
        inset.top -= self.headerBtn.lb_height;
        self.tableView.contentInset = inset;

    }completion:^(BOOL finished) {//刷新控件缩回到用户看不到的位置后,更新刷新控件以及内部子控件的状态
        self.headerBtn.hidden = NO;
        self.loadingView.alpha = 0.0;
        [self.loadingView stopAnimating];
    }];
}

ok,效果实现基本结束了,感谢您的阅读,不足之处欢迎指正

点击查看代码实现

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容