【UIKit】表格 UITableView

UITableView的使用介绍

 

官方文档:Table View Programming Guide for iOS

UITableView基本使用基本步骤

  1.  准备数据源的数组
  2.  遵循的协议UITableViewDataSource  、UITableViewDelegate、UITableViewDataSourcePrefetch(数据预加载)
  3.  使用表格必须实现DataSource三个代理协议方法(确定表格的块、行、每行的内容),根据需求实现其他代理。
  4.  数据源(一般为控制器)根据索引路径(indexPath:即定位到唯一的一个单元格)为某一个单元格提供数据
  5.  索引路径是NSIndexPath对象,拥有两个属性:段(section)、行(row),即通过这两个属性定位UITableView中的唯一一个单元格cell
  6.  掌握代理方法实现点击单元格事件响应(打开下一页。。。。。。)【didSelect….】
  7.  使用代理方法添加编辑按钮及响应事件单元格[editActionForRowAtIndexPath  、   will/didEditing…..]
  8.   实现editActionsForRowAtIndexPath:方法  返回值为数组
  9.   创建UITableViewRowAction对象(需要几个操作,创建几个)
  10.     对表格进行编辑后一定记得刷新表格【reloadData】

UITableviewDelegate协议

    官网文档:UITableViewDelegate

    UITableviewDelegate作用:主要是对UITableview的整个生命周期的各过程或者各种事件状态设置接口,方便你在某种时刻或者事件状态下做自定义操作。具体分为:

1.某个视图模块(cell、header、footer)的将要显示结束显示.

2.某个视图在某个位置index/section的高度/预留高度。

3.传图UIView作为header、footer的视图。

4.附属按钮点击时候

5.高亮状态的三个状态。

6.选择取消选择的两个状态(will和didEnd)

7.编辑状态编辑类型设置(没有、删除、插入)、自定义删除按钮的字【titleForDelecteXXXX】、自定义增加多个按钮【editActionForRow】,注意自带的删除将会消失,所以可以自己加上,最先放入的在右边、是否首行缩进(indent)??

8.移动时的操作接口

9.复制与粘贴菜单操作(如果需要的实现相关三个代理【performAction】)

10.与焦点(focus)有关的几个接口【不知道干嘛用的】

备注:使用代理方法的时候,可以直接打划线的关键字,就会给出相关的代理提示。

具体查看官网文档。

TIPs: TableView的高度自适应,将tableView.rowHeight = UITableView.automaticDimension (前提做好约束)

[官网文档:Self-Sizing Table View Cells]

UITableViewDataSource协议

官网文档:UITableViewDataSource

1.确定表格模块是,sectionNumber。

2.确定每个块中有多少行。

3.每行的数据填充。

4.header与footer的text填充,【疑问:字体颜色样式怎么控制?自定义header覆盖吗?】。

5.编辑(插入、移动、删除的数据源处理)

6.添加右侧栏的侧栏字母序列【注意:tableView的style必须为plain】

7.右侧索引字母对应的某个模块,相当于将右侧索引字母与模块关联起来。

扩展:右侧索引字母的颜色与tableView的tintColor一致。

UITableViewDataSourcePrefetch协议

主要就两个方法,一个预加载数据(比如在其中进行数据源的预加载处理),另一个取消预加载,可以提高很大性能,大量数据建议使用。

对表格进行增删

注意点:1、确定删除位置

2、先更新数据源【特重要,不然会发生错误终止,因为行数不对应/不够,】

3、删除或插入行

4、更新表格

示例:评分cell的显示与隐藏

    /**
     *  选择评分
     */
    func tableViewSelectScore(){
        self.tableview?.beginUpdates() //开始更新表格(一般是用于插入或删除行)
        let tempIndexPath = [NSIndexPath(forRow: 2, inSection: 0)] //首先确定哪一个路径改变(某一段的某行(基数是从0开始的)))
        if showScore{//如果已经点开拉评论
            //说明评论已经打开,需要取消掉评论行
            //1.取消前需要处理数据源,行数减少一个
            self.titleArray.removeAtIndex(2)
            //2移除那行
            self.tableview?.deleteRowsAtIndexPaths(tempIndexPath, withRowAnimation: UITableViewRowAnimation.Right)//从右边划出
            self.showScore = false  //如果是有一个可选显示的,可以设一个标记变量

        }else{
        self.titleArray.insert("", atIndex: 2)   //很重要,在表格对应的数据源添加数据,不然就会发生表格行数不够的错误,引起程序终止
        self.tableview?.insertRowsAtIndexPaths(tempIndexPath, withRowAnimation: UITableViewRowAnimation.Left) //插入位置是【参数是数组】,及动画效果(从左到右)

        self.showScore = true  //显示星星
        }
        

        self.tableview?.endUpdates() //结束更新

    }

补充提示:

1、表格视图的Footer 与header,注意与sectione的footer和header不是同一个
3、如何不显示空表格的分割线?
       使用如下语句self.table.tableFooterView = [[UIView alloc] init];
       或者:将UITableView的separatorStyle属性设置为UITableViewCellSeparatorStyleNone,全部cell取消分割线。
 

UITableViewCell

1、系统单元格组成
      单元格(UITableViewCell)是tableView的组成单元,每一个单元格都是一个UITableViewCell对象,默认情况下,一个单元格具有一个icon图片、一个title、一个detail title,以及一个accessory
2、系统自带单元格样式是?(四个)

3、使用单元格时更常用的是使用Xib自定义单元格,但是记得需要在TableView中调用注册方法


4、单元格的配置细节(在cellForAtRowIndexPath方法中实现)
      在UITableView内部有一个缓存池,使用 (UITableViewCellStyle) reuseIdentifier:(NSString *)方法指定一个可重用标识,就可以将复用cell放到缓存池
      a、 设置常量,获取到IB中TableViewCell中Identifier(在IB中应该设置,否则可能出错)//通过Xib自定义的就需要注册在tableView中才可以复用
      b、 获取cell(从缓冲池中),使用dequeueReusableCellWithIdentifier方法实现,【注意,在后面转换为UITAbleViewCell(as! UITAbleViewCell)】
      c、 获取数据源
     d、 设置Cell的内容

1、    如果包含多个section模块,那么数据源建议放在二维数组读取

2、    记得设置section数目

3、   如果section的header以及footer仅仅需要显示一些文字提示,如下图所示,则可以直接调用tableview的代理方法titleForHeaderInSection返回值为String)来设置

4、  可以设置sectionIndexTitlesForTableView方法显示索引内容(右侧显示),还可以设置索引的各种属性(颜色、背景、点击背景)【通过tableView的属性设置】?

5、 【tip】可以通过清除背景颜色达到索引的整体一致.sectionheader颜色可以改变

自定义header/Footer

1、 还需要添加一些UI控件或定制样式,这就需要通过tableview的代理方法viewForHeaderInSection返回值为UIView)内进行定制

2、 定制思想:创建需要的控件对象,配置好控件对象,创建一个视图对象,将控件对象添加到视图对象并布局好即可,做好相应的响应处理(必要时)

refreshControl

如果直接使用UITableViewController,是可以自带刷新控件的,默认是不使用,需要则设置true, 但是只可以下拉刷新,

使用的几个注意点,

1.下拉后自动执行

     // self.refreshControl?.beginRefreshing() //!!!:

     会立即自动调用tableView.ReloadDatatableView cellForRow xxx的代理方法,给cell填充的方法,但是不会执行

func numberOfSections(in tableView:UITableView) ->Int,

所以需要注意:此时数据源最好不变,否则可能会导致越界异常

2.需要手动在一定的逻辑处结束刷新。

self.refreshControl?.endRefreshing()  //之后显示重新加载table

默认的footer(如果不设置为0.001f的话)【此图片用于评论区】

UITableView顶部留白问题

UITableView(Plain)取消footer和header的粘黏

示例代码

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        /// 取消粘连
        let sectionHeaderHeight:CGFloat = 30;
        let sectionFooterHeight: CGFloat = 55
        let offsetY = scrollView.contentOffset.y
        if (offsetY <= sectionHeaderHeight && offsetY >= 0) {
            scrollView.contentInset = UIEdgeInsets.init(top: -offsetY, left: 0, bottom: -sectionFooterHeight, right: 0)
        } else if (offsetY >= sectionHeaderHeight) {
            scrollView.contentInset = UIEdgeInsets.init(top: -offsetY, left: 0, bottom: -sectionFooterHeight, right: 0)
        }else if (offsetY >= scrollView.contentSize.height - scrollView.frame.size.height - sectionFooterHeight && offsetY <= scrollView.contentSize.height - scrollView.frame.size.height){
            scrollView.contentInset = UIEdgeInsets(top: -offsetY, left: 0, bottom: (scrollView.contentSize.height-scrollView.frame.height-sectionFooterHeight), right: 0)
        }
    
    }

使用 Group 注意事项

如果我们不想保留 tabelView 的 header和 footer沾粘效果。可以利用 group 样式来取消,但是同时需要注意设置 headerView 和 footerView 的高度。

设置 tableViewFooterHeader

let header = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))
let footer = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))

tableView.tableViewHeaderView = header
tableView.tableViewFooterView = footer

设置 HeaderView 高度

以下方式视情况二选一,优先级: 代理方法>直接设置

直接设置

tableView.sectionHeaderHeight = CGFloat.leastNormalMagnitude

代理方式设置

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return CGFloat.leastNonzeroMagnitude // 或者0.01
}

设置 FooterView 高度

以下方式视情况二选一,优先级: 代理方法>直接设置

直接设置方式

tableView.sectionFooterHeight =  CGFloat.leastNormalMagnitude

代理方法设置

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return CGFloat.leastNonzeroMagnitude //或者0.001, 注意0.01(或者CGFloat.leastNormalMagnitude)在 iOS14中还是有35空白
}

以上高度大部分可以直接设置0.01(footerView代理中需要使用0.001/CGFloat.leastNonzeroMagnitude),但是建议设置 `CGFloat.leastNormalMagnitude`,原因在于Cell滑动工程中可能会有白影闪过

最小 Float 正数值

Objective-C:  CGFLOAT_MIN

Swift:

CGFloat.leastNormalMagnitude :最小的正规则数

CGFloat.leastNonzeroMagnitude:最小正数(如果支持 subnormal,会比 CGFloat.leastNormalMagnitude 小,否则就是相等的)

关于 subnormal value 也叫 denormal number,统一称作非规格化浮点数​​​​​​​

修改 Header Title 样式

在多组标题时,代理方法只能传入 title, 那要如何修改样式了(在不重写 headerView前提下)?

只需要实现 代理方法的 willDisplayHeaderView 方法, 然后获取相应对象,修改即可。

 func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        guard let header = view as? UITableViewHeaderFooterView else {
            return
        }
        header.textLabel?.font = UIFont.systemFont(ofSize: 12, weight: .medium)
        header.textLabel?.textColor = UIColor(hexString: "#787878")
        header.contentView.backgroundColor = UIColor(hexString: "#F8F8F8") // 注意直接修改 backgroundColor 没有效果。一般为nil 
    }

 section Header 取消背景默认灰色(不重写 headerView方式)

guard let header = view as? UITableViewHeaderFooterView else {
    return
}

//header.tintColor = .clear  // 可以实现,但是不推荐,可能影响其他控件
if #available(iOS 14.0, *) {
    header.backgroundConfiguration = UIBackgroundConfiguration.clear() 
} else {
    header.backgroundColor = .clear
}

兼容原因:在 iOS14后,增加了现代化配置 Cell ​​​​​​​功能,会在 background配置某些view.可参考 iOS14的 Modern cell configration给我们带来什么

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值