UITableView运用指南

概述

一般遇到很多相同结构的视图进行同一方向摆放时,比方一般app的设置页面、通讯录等,运用UITableView是一个十分适宜的方案。

基本介绍

风格款式:

这个特点是UITableView最基本的特点,共有两种

  • UITableViewStylePlain:默许款式

    • plain 形式下,假如 tableview 有多个 section(分区、分组),组与组之间默许是没有距离的。

    • 一起组头或组尾会有 sticky 作用(粘性作用、悬停作用),即表格翻滚时组头与组尾会自动逗留,而不是跟从单元格一同移动。

    • 一起plain形式下的tableView能够有一个section索引,作为一个bar在table的右边(例如A ~ Z)。你能够点击一个特定的标签,跳转到方针section。

    • 例如:iOS中「通讯录」便是典型运用

      UITableView使用指南

  • UITableViewStyleGrouped:分组款式

    • grouped 形式下,假如 tableview 有多个 section,组与组之间默许是有距离的。

    • 在表格翻滚的一起组头与组尾会随之翻滚、不逗留,不会有 sticky 作用(粘性作用、悬停作用)。

    • Group类型默许设置tableView灰色背景色,cell为白色背景色,section外边缘设置浅灰色边框,cell设置浅灰色间隔线

    • 例如:iOS中「设置」便是典型运用

      UITableView使用指南

踩坑记载:

在iOS15中,假如运用UITableViewStylePlain款式树立TableView,假如给section增加一个header那么会呈现一个现象,便是在这个header上方会呈现一个空白区域。这个空白区域是由于在iOS15中UITableView中引进了一个新的特点sectionHeaderTopPadding,这个特点默许是22,假如不需求这块空白,改为0即可,代码如下:

let tableView = UITableView()
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
} else {
// Fallback on earlier versions
}

单元格Cell

UITableView的每行数据都是一个UITableViewCell:

  1. 每个Cell运用IndexPath来表明位置,换言之UITableView中的数据只有行的概念,没有列的概念
  2. IndexPath又分为section和* row***,每个section为一组,其间能够包含多个行row。**

关于Cell的重用

需求注意的是 TableView 有必要运用重用机制 ,当cell滑出屏幕的时候 cell会被体系收回,在下面cell即将显现时会调用之前收回的cell,这样就不必每次都创立毁掉,节约内存一起节约时间,假如不运用重用机制,每次都创立新的cell 是十分消耗内存和功能的

// 有必要实作的办法:Cell重用,然后设定Cell的内容
func tableView(_ tableView: UITableView,
        cellForRowAt indexPath: IndexPath) -> UITableViewCell {
 // 取得 tableView 目前运用的 cell
 let cell = tableView.dequeueReusableCell(
  withIdentifier: "Cell",
  for: indexPath) as UITableViewCell// 设置显现的内容
 if let myLabel = cell.textLabel {
  myLabel.text = "xxxx"
 }
​
 return cell
}

Cell的UI和布局

UITableView中每行数据都是一个UITableViewCell,在这个控件中为了显现更多的信息,iOS现已在其内部设置好了多个子控件以供开发者运用。假如咱们检查UITableViewCell的声明文件能够发现在内部有一个UIView控件(contentView,作为其他元素的父控件)两个UILable控件(textLabel、detailTextLabel)、一个UIImage控件(imageView),别离用于容器、显现内容、概况和图片。

UITableView使用指南

假如直接运用UITableViewCell则默许共有四种Style设定:

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
  UITableViewCellStyleDefault,  // 左面显现textLabel(不显现detailTextLabel),imageView可选(显现在最左面)
  UITableViewCellStyleValue1,  // 左面显现textLabel、右侧显现detailTextLabel(默许蓝色),imageView可选(显现在最左面)
  UITableViewCellStyleValue2,  // 左面顺次显现textLabel(默许蓝色)和detailTextLabel,imageView可选(显现在最左面)
  UITableViewCellStyleSubtitle  // 左上方显现textLabel,左下方显现detailTextLabel(默许灰色),imageView可选(显现在最左面)
}; 

UITableView使用指南

Cell的特点

accessoryView

在contentView的右边,还有一个accessoryView,这个View是用来作为功用键运用,在iOS中称为拜访器,支持显现不同的图标,点击能够触发不同的事情

UITableView使用指南

这个View的设定是经过设置UITableViewCell中的accesoryType特点完成的:

public enum AccessoryType : Int, @unchecked Sendable {
  case none = 0 // 不显现任何图标
  case disclosureIndicator = 1 // 跳转指示图标
  case detailDisclosureButton = 2 // 内容概况图标和跳转指示图标
  case checkmark = 3 // 勾选图标
  @available(iOS 7.0, *)
  case detailButton = 4 // 内容概况图标 
}

默许状况如图所示:

UITableView使用指南

Cell的分割线
// 设置分割线端距,这儿表明separator离左面和右边均80像素
myTableView.separatorInset = UIEdgeInsets(top: 0, left: 40, bottom: 0, right: 40)
myTableView.separatorStyle = .singleLine  // 分割线的款式
myTableView.separatorColor = .red  // 分割线色彩
隐藏部分Cell的分割线

因为TableView的风格设置是针对整个tableView的,假如设置myTableView.separatorStyle = .singleLine,则一切的cell都会有分割线,假如要隐藏部分cell的话就需求一点点小trick

在要显现cell的时候将cell的分割线inset左右各设为cell宽度的一半

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
   if indexPath.section == 1 {
     cell.separatorInset = .init(top: 0, left: cell.bounds.width / 2, bottom: 0, right: cell.bounds.width / 2)
   }
}
Cell选中款式
// cell的选中款式
cell.selectionStyle = .default // 默许点击时为灰色
cell.selectionStyle = .none   // 设置为none点击时无反应 
// 这儿要注意一下,其实还有.grey和.blue但作用和.default是相同的
// 在iOS7的时候更改了,然后假如想要设置为其他色彩,则要设置selectedBackgroundView
// cell的选中款式为其他色彩
cell.selectionStyle = .default
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView?.backgroundColor = .blue

UITableView的运用:

  • 在controller中引进UITableView类型的变量,然后设置相应的数据源和代理:

    tableView.delegate = self
    tableView.datasource = self
    
  • 表格分组section的DataSource办法的调用时序:

UITableView使用指南

DataSource数据源:需求在Controller引进UITableViewDataSource协议

  • 回来表格视图的Section数:numberOfSections

    func numberOfSections(in tableView: UITableView) -> Int {
      // 回来section的数量
      return 1
    }
    
  • 设置 section中的row行的个数:

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      // 回来Section中的row行数
      return 1
    }
    
  • 回来Section的头部View:

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
      // 回来对应Section的头部
      return UIView()
    }
    
  • 回来Section的尾部View:

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
      // 回来对应Section的尾部
      return UIView()
    }
    

UITableViewDelegate:需求在Controller引进UITableViewDelegate协议

  • 回来每个cell对应的行高:

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
      if indexPath.section == 0 {
        // section0 的cell行高为70
        return 70
      } else if indexPath.section == 1 {
        // section1 的cell行高为140
        return 140
      }
      // 默许行高
      return 106
    }
    
  • 回来Section头部的高度:

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        if section == 0 {
          return 0.01
        }
        if (isShowUrlCell && section == 5) || (!isShowUrlCell && section == 4) {
          return 0.01
        }
        return 8
      }
    
  • 回来Section尾部的高度:

    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
      return 0.01
    }
    
  • Cell的点击事情:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      if indexPath.section == 1 {
        // 针对section1操作
      } else if indexPath.section == 2 {
        // 针对Section2操作
      } else {
        // 默许操作
      }
    }
    

UITableView的一些惯例函数/功用运用

  • 更新Cell,从头加载一切Cell

    • 此办法可从头加载用于构建表格的一切数据,包含单元格、节页眉和页脚、索引数组等。为了进步功率,表格视图只从头显现那些可见的行。假如表因从头加载而缩小,它会调整偏移量。表视图的代理或数据源在它期望表视图彻底从头加载其数据时调用此办法。不应在插入或删去行的办法中调用它,尤其是在经过调用和完成的动画块中

      tableView.reloadData()
      
  • Cell的左滑右滑

    // 从左向右滑动
    func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
      let config = UISwipeActionsConfiguration(actions: [UIContextualAction(style: .normal, title: "点赞", handler: { _,_,_ in print("like")
      })])
      return config
    }
    // 从右向左滑动
    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
      let config = UISwipeActionsConfiguration(actions: [UIContextualAction(style: .destructive, title: "删去", handler: {_,_,_ in print("delete")})])
      return config
    }
    
  • iOS中会对scrollview进行显现优化,以避免在安全区域显现,这儿给出怎么设置不自动调整位置

    // 设置为.never即可让tableview的显现覆盖安全区域
    tableView.contentInsetAdjustmentBehavior = .never
    

TableView的功能优化

  1. UITableView 功能优化 –
  2. tableView功能优化 –