美文网首页iOS资料O~1iOS UI
iOS-UITableView你需要掌握的属性

iOS-UITableView你需要掌握的属性

作者: 小小小阿博er | 来源:发表于2016-06-06 14:57 被阅读2529次

    背景

    • 在现今的开发中,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,效果实现基本结束了,感谢您的阅读,不足之处欢迎指正

    点击查看代码实现

    相关文章

      网友评论

      本文标题:iOS-UITableView你需要掌握的属性

      本文链接:https://www.haomeiwen.com/subject/xdghdttx.html