美文网首页iOS学习Tool
iOS UITableViewStylePlain和UITabl

iOS UITableViewStylePlain和UITabl

作者: codeTao | 来源:发表于2018-09-14 02:10 被阅读2次

    创建UITableView 时, 需要设置TableView样式, 默认有两种样式:UITableViewStylePlain, UITableViewStyleGrouped

    UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style: UITableViewStyleGrouped]
    

    下面先介绍下, 这两种样式以及区别:

    一. UITableView样式介绍

    UITableViewStylePlain 介绍

    在tableView的UITableViewStylePlain中,当一个section的rows有一部分可见时,section的header和footer浮动在内容顶部。plain style的tableView可以有一个section索引,作为一个bar在table的右边(例如A ~ Z)。你可以点击一个特定的标签,跳转到目标section。
    例如下图:

    contacts.png

    UITableViewStyleGroup 介绍

    在tableView的UITableViewStyleGroup中,所有单元格拥有一个默认的背景颜色和默认背景视图。背景视图为特定section中的所有cell提供可视分组。例如,一个group可以是一个人的名字和标题,另一个group可以是电话,电子邮件帐户等。可参考iphone“设置”程序。
    例如下图:

    settings.png accessibility.png

    Group类型默认设置tableView灰色背景色,cell为白色背景色,section外边缘设置浅灰色边框,cell设置浅灰色间隔线。如下图:

    设置.png

    二:区别总结:

    UITableViewStylePlain使用

    1.plain类型有多段时,滚动时Section Header 在顶部停留,有些界面比如设置界面,这些新特性将显得多余。(自带效果)
    2.plain类型默认section之间没有中间的间距和头部间距(想让plain类型的section之间留有空白,需要在UITableView代理方法中return自定义的headerView和footerView,并在自定义的headerView 和 footerView 里面重写setFrame方法)

    解决方案:让plain类型的UITableView的section头部视图不停留(取消粘性效果)
    • 方法一: 网上好多都是这个方法. 这个代码是通过scroll偏移量来监听和改变你的tableView的contentInset 可见很不好(试试就知道)
    //去掉UItableview headerview黏性(sticky)
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        CGFloat sectionHeaderHeight = 30;
        if (scrollView.contentOffset.y <= sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
            scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
        } else if (scrollView.contentOffset.y >= sectionHeaderHeight) {
            scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
        }
    }
    
    • 方法二: 在自定义section的headerView中, 重写setFrame: 方法来重载table的section.
      • 注意:setFrame方法中需要拿到重载的table和section!
    - (void)setFrame:(CGRect)frame {    
        CGRect sectionRect = [self.tableView rectForSection:self.section];
        CGRect newFrame = CGRectMake(CGRectGetMinX(frame), CGRectGetMinY(sectionRect), CGRectGetWidth(frame), CGRectGetHeight(frame)); 
        [super setFrame:newFrame];
    }
    

    UITableViewStyleGroup 使用

    解决方案:去掉 UITableViewStyleGroup类型的多余间距
    应用场景一.png
    应用场景一: sction的头部视图和尾部视图,无任何内容
    • 此应用场景需要分两步做:
      第一步: 处理第一个section上边多余间距(2种方法)
    • 方法一: tableView的tableHeaderView属性
      • 注意: 设置tableView头部视图的高度为特小值,但不能为零,若为零的话,iOS会取默认值,就无法消除头部间距了。
    - (void)viewDidLoad {
      //设置代理
        tableView.delegate = self;
      //隐藏UITableViewStyleGrouped上边多余的间隔
      tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
    }
    
    • 方法二: 设置顶部额滚动区域
        tableView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0);
    
    • 补充: 属性tableHeaderView和contentInset 结合使用, 可以设置表格第一个cell顶到最顶部
      tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
        tableView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0);
    

    第二步: 处理每个section下边多余间距(2种方法)

    • Group样式, 默认每一组都会有头部和尾部间距, 这两个间距保留一个就可以了.另一个间距设置为0.

    • 方法一: tableView 属性sectionHeaderHeight 和 属性sectionFooterHeight , 处理多余间距

        //设置tableView主间距为20
        tableView.sectionHeaderHeight = 0;
        tableView.sectionFooterHeight = 20;
    
    • 方法二: 调用tableView的代理方法 , 设置尾部视图的高度,
      • 注意: 去掉的视图, 返回值不能为0,否则系统启用默认值。返回的高度使用极小值CGFLOAT_MIN。
      • 注意2: 调用下面两个tableView代理方法后, sectionHeaderHeight属性和sectionFooterHeight属性设置的值失效.
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
        return 44;
    }
    // 注意:return height 为 0,则 height 被设置成默认值
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
        return CGFLOAT_MIN;
    }
    
    应用场景二.png

    应用场景二: sction有头部标题 尾部标题

    此应用场景两种方法取其一, 可以同时处理section顶部间距和中间间距

    • 方法一: 设置 tableView 属性sectionHeaderHeight 和 属性sectionFooterHeight , 可同时处理section多余顶部间距和中间间距
    tableView.sectionHeaderHeight = 30;
    tableView.sectionFooterHeight = 0;
    
    • 方法二:调用tableView的代理方法 , 设置头部视图和尾部视图的高度
    //第二步:隐藏UITableViewStyleGrouped下边多余的间隔
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
        return 30;
    }
    // 注意:此时可以设置为0
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
        return 0;
    }
    

    应用场景三: section自定义头部视图和尾部视图

    • 调用下面tableView代理方法 自定义头部视图和尾部视图后, 不需要做顶部间距处理, 第一个section头部视图会自动顶到最顶部.
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    }
    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
    }
    
    • 中间间距 只需要通过tableView代理方法, 调整头部视图或者尾部视图各自的高度即可.
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
        return 30;
    }
    //注意:此时可以设置为0
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
        return 0;
    }
    
    

    三. 在 Storyboard 中 0 代码搞定顶部多余间距

    没用 Storyboard 的同学使用上面的代码就 OK 了;
    而在 Storyboard 中可以 0 代码搞定这个事:

    首先,在第一个 Section 的上面拖进来一个空 UIView

    image

    然后选中这个 UIView 的 Runtime Attributes 栏,添加一个 frame 的 KeyPath

    image

    这样头部的间隔就乖乖的不见了:

    image
    刨根问底 UITableViewHeader 的猫腻

    为什么刚才说 0.1 和 CGFLOAT_MIN 是等效的呢?经过研究,这个高度值的影响大概是这样的:

    1. 若传入的 height == 0,则 height 被设置成默认值
    2. 若 height 小于屏幕半像素对应的高度,这个 header 不在另一个像素渲染

    半像素也就是 1.0 / scale / 2.0,如在 @2x 屏上是 0.25
    直观的感受下,假如这个 height 被设置成 0.5 的样子:

    image

    导航栏下面的阴影线看上去宽了 0.5 像素的,Done。

    参考:
    https://www.jianshu.com/p/764ed5aa46cf
    http://blog.sina.com.cn/s/blog_801997310102vpa1.html
    https://www.cnblogs.com/lurenq/p/8133973.html

    由于笔者水平有限,文中如果有错误的地方,或者有更好的方法,还望大神指出。
    附上本文的所有 demo 下载链接,【GitHub】
    如果你看完后觉得对你有所帮助,还望在 GitHub 上点个 star。赠人玫瑰,手有余香。

    相关文章

      网友评论

        本文标题:iOS UITableViewStylePlain和UITabl

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