UITableView在app中的应用十分广泛,接下来我们就来简单学习一下UITableView。

一、基本认识

UITableView继承于UIScrollView,只不过前者只能纵向滑动。UITableView在父类的基础添加了一些属性:

(这些属性是没有遵守代理时的UITableView的本身的属性),这些属性在后面会介绍。

然后再来看看tableview的结构:

二、创建一个UITableView

首先我们在控制器的viewdidload方法中,创建一个UITableView(一般是将这个UITableView作为属性变量)。

//viewDidLoad中
self.tableView = [[UITableView alloc]
initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height) style:
UITableViewStyleGrouped];

需要指出的是UITableView的style属性有两个:UITableViewStyleGrouped,UITableViewStylePlain。二者之间的区别:二者的区别。

然后我们对这个UITableView本身的属性进行设置:

//ViewDidLoad中//分割线颜色self.tableView.separatorColor = [UIColor blackColor];//分割线类型self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;//自适应的row的高度self.tableView.estimatedRowHeight = 120;self.tableView.rowHeight = UITableViewAutomaticDimension;//背景颜色self.tableView.backgroundColor = [UIColor whiteColor];self.tableView.delegate = self;//这个代理实际上是控制数据源的方法self.tableView.dataSource = self;[self.view addSubview:self.tableView];

分割线的颜色不用多说,是UIColor类型的;分割线控制的是每一个段中每一个row的分割线的类型,它的类型有三种:

typedef NS_ENUM(NSInteger, UITableViewCellSeparatorStyle) {UITableViewCellSeparatorStyleNone,UITableViewCellSeparatorStyleSingleLine,UITableViewCellSeparatorStyleSingleLineEtched
NS_ENUM_DEPRECATED_IOS(2_0, 11_0,
"Use UITableViewCellSeparatorStyleSingleLine for a single line separator.")
}

第一种类型没有分割线,第二种类型有分割线,第三种类型在xcode9.4.1中已经没有使用了,使用第二种来代替。

第一种类型效果

第二种类型效果

然后是tableview中每个section中的row的高度 ,由于有时每个row中的内容是变化的,所以row的高度需要自适应内容的高度

首先我们要估计一个row的高度,就是estimatedRowHeight,然后再设置实际上的rowheight。

背景颜色不用多说,然后后面的两个都是tableView代理属性,接下来会讲到。

三、代理方法

tableview应该至少有两个代理一个是数据源的代理:UITableViewDataSource,另一个是事件处理的代理:UITableViewDelegate。

1、数据源代理及方法实现

在实现数据源的方法之前我们需要有自己的数据,因此建立一个模型SectionGroup,用来配置每个section和每个row中的数据

//sectionGroup.h
#import <Foundation/Foundation.h>@interface SectionGroup : NSObject
//每个段的头部
@property (nonatomic,copy)NSString * sectionHeader;
//每个段的尾部
@property (nonatomic,copy)NSString * sectionFooter;
//一般出现在右边作为每个section的快速访问
@property (nonatomic,copy)NSString * sectionIndex;
//设置一个装row的数组
@property (nonatomic,strong)NSMutableArray * rowsArray;+(instancetype)sectionGroup;
@end//sectionGroup.m
#import "SectionGroup .h"@implementation SectionGroup
+(instancetype)sectionGroup{SectionGroup * section = [[SectionGroup alloc]init];section.sectionHeader = @"这是组的头部";section.sectionFooter = @"这是组的底部";section.sectionIndex = [NSString stringWithFormat:@"%d",arc4random_uniform(10)];section.rowsArray = [NSMutableArray array];for (int i = 0 ; i < 10; i++) {//每个section中有10个rowNSString * number = [NSString stringWithFormat:@"这是第%d行",i+1];[section.rowsArray addObject:number];}return section;
}
@end

然后我们在viewcontroller中定义一个数组datalist用来装需要配置的数据,接着我们重写datalist的get方法,因为在点语法点到datalist时,我们需要给相应的对象配置数据。

//懒加载自己的数据
-(NSMutableArray *)dataList{if (_dataList == nil) {_dataList = [NSMutableArray array];for (int i = 0; i<4; i++) {//datalist里面装section//一共有4个sectionSectionGroup * section = [SectionGroup sectionGroup];[_dataList addObject:section];}}return _dataList;
}

这样一来,我们就实现了一个类似二维数组的datalist,首先datalist中装的是一个个的section,每一个section中又装的是一个个的row(一个section中是一个rowArray数组),这样一来我们就实现了文章开头那个tableview结构图的数据形式。

然后我们开始着手将这些数据形式通过UI展示出来,首先我们事先数据源代理的两个方法:numberOfSectionsInTableView: 和 numberOfRowsInSection:


-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{//返回datalist中对象数量,实际就是section的数量return self.dataList.count;
}- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {//由于无法在当前类中访问section中的rowsArray,所以我们将每一个section取出来SectionGroup * sections = [self.dataList objectAtIndex:section];return sections.rowsArray.count;
}

这些设置完毕后,就会得到一个除了header和footer还有分割线之外没有其他任何内容的tableview,因此我们需要去设置每个row对应的cell,再这之前我们需哟啊看一下row和cell的结构关系:

从图中我们可以看出每一个row就是一个cell,且每一个cell都是可以定制的,每一个cell主要包括三个部分,左边的imgaview,中间的textLabel,最右边的accessoryview。

现在我们可以设置cell,需要实现的代理的方法是:cellForRowAtIndexPath:

- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {//使用苹果提供的缓存池机制//定义一个静态的cell标识符static NSString * cellID = @"cell";//首先从缓存池中找标识符为cell的cellUITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellID];//如果没有找到,则创建if (cell == nil) {cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];}//先取出对应组,再取出对应行的信息 相当于一个二维数组SectionGroup * sections = [self.dataList objectAtIndex:indexPath.section];NSString * numberString = [sections.rowsArray objectAtIndex:indexPath.row];//设置cell里面的视图int random = arc4random_uniform(8);if (random == 2||random == 6) {//detail只会在cell的类型是subtitl的时候才会显示cell.detailTextLabel.text = @"我家的后面有一个很大的园,相传叫作百草园。现在是早已并屋子一起卖给朱文公的子孙了,连那最末次的相见也已经隔了七八年,其中似乎确凿只有一些野草;但那时却是我的乐园。";}else{cell.detailTextLabel.text = @"说明性的文字";}//detailTextLabel是处于textlabel下的一段比较小的文字,一般是对内容的概括cell.detailTextLabel.numberOfLines = 0;cell.imageView.image = [UIImage imageNamed:@"timg"];cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;//将这个数据显示到对应的cell上cell.textLabel .text = numberString;return cell;
}

由于这个方法返回的是一个UITableViewCell,所以我们需要创建一个对应的对象然后返回,但是有一个问题,就是当我们滑动tableview使一个row消失,另一个row出现时,新出现的的row实际上新创建的,这样是很浪费内存的,有没有一种方法可以使新出现的row使用已经消失的row,改变的只是它的内容呢?苹果提供了一种缓存池机制可以实现cell的复用。要使用这种机制,我们需要定义一个静态的标识符(Identifier),然后在创建时使用[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]方法为新创建的这个cell指定标识符,之后每一次设置cell都优先从当前这个tableview中去找标识符对应的那个cell,然后改变cell的内容即可。

cell设置完毕后,一个简单的tableview视图就算完成了,接下来我们要处理相应的事件了

2、UITableViewDelegate代理方法实现

1、row的删除

对于row的删除需要实现的方法是:editActionsForRowAtIndexPath:


-(NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{UITableViewRowAction * deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault
title:@"删除"
handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {//删除就是删除掉datalist中的数据,这样在重新加载时就加载新的数据了[self.dataList removeObjectAtIndex:indexPath.row];//删除后重新加载表[tableView reloadData];}];NSArray * actions = @[deleteAction];return actions;
}

由于返回值是一个 UITableViewRowAction的数组,所以我们需要创建UITableViewRowAction,这里初始化时有一个rowActionWithStyle,

typedef NS_ENUM(NSInteger, UITableViewRowActionStyle) {UITableViewRowActionStyleDefault = 0,UITableViewRowActionStyleDestructive = UITableViewRowActionStyleDefault,UITableViewRowActionStyleNormal
} NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

实际上就只有两种类型,normal类型的背景颜色是灰色的,default的背景颜色是红色的。

然后实际上的操作实在block中完成的,实际操作代码这里不做赘述,但需要注意的是一定要在删除后重新加载数据。

最后将这个action装进一个数组中,返回这个数组就行了。

2、row的点击事件的代理方法实现

这个事件需要实现的代理方法是: didSelectRowAtIndexPath:


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{NSString * string = [NSString stringWithFormat:@"第%lu段 第%lu行",indexPath.section,indexPath.row];//显创建提示框控制器UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:string preferredStyle:UIAlertControllerStyleAlert];//样式是alert说明是提示框在中间弹出来,sheet样式是在下面弹出来//然后创建提示框行为,就是选项UIAlertAction * sureAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {}];UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {}];//将行为添加到控制器上面[alert addAction:sureAction];[alert addAction:cancelAction];[self presentViewController:alert animated:YES completion:nil];
}

3、header与footer的设置

需要实现的方法是:titleForHeaderInSection: 和 titleForFooterInSection:

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{SectionGroup * sections = [self.dataList objectAtIndex:section];return sections.sectionHeader;
}
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{SectionGroup * sections = [self.dataList objectAtIndex:section];return sections.sectionFooter;
}

我们之前模型SectionGroup只是数据的形式,显示到对应footer和对应的header上需要通过代理来实现。实现的思路都是先取出对应的数据,然后返回给代理。

4、sectionindex的设置

需要实现的方法: sectionIndexTitlesForTableView:

-(NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{NSMutableArray * indexArray = [NSMutableArray array];for (SectionGroup * sections in self.dataList) {NSString * string = sections.sectionIndex;[indexArray addObject:string];}return indexArray;
}

iOS之UITableView相关推荐

  1. iOS 8 UITableView分隔符插入0不起作用

    本文翻译自:iOS 8 UITableView separator inset 0 not working I have an app where the UITableView 's separat ...

  2. iOS 关于UITableView的黑科技

      UITableView是我们最常用的控件了,今天我就来介绍一些关于UITableView的黑科技和一些注意的地方. 1.修改左滑删除按钮的高度   左滑删除这是iOS最先发明的,之后安卓开始模仿. ...

  3. 【IOS】从android角度来实现(理解)IOS的UITableView

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3403124.html   本人从在学校开始到现在上班(13年毕 ...

  4. iOS之UITableView组头组尾视图/标题悬停

    最近笔者在公司的iOS开发中,有一个iOS开发同事跑来问了两个问题:1.给UITableView设置了组头和组尾视图,但是一直显示不出来?2.UITableView的section的header和fo ...

  5. iOS 15 UITableView Section间距变大

    解决方法: 单页面修改 if (@available(iOS 15.0, *)) { [self.tableView setSectionHeaderTopPadding:0.0f]; } 全局修改 ...

  6. iOS开发-UITableView顶部图片下拉放大

    关于顶部图片下拉放大,在用户展示的个人中心显示用户个人头像信息,设置UITableView的headerView实现,UITableView继承自UIScrollView,同样的设置UIScrollV ...

  7. IOS中UITableview中封装九宫格

    第一步引入SecondNav目录即可 第二步引入头文件 #import "DIYTableView.h" #import "invoiceInfo.h" 实现协 ...

  8. IOS中UITableView异步加载图片的实现

    本文转载至 http://blog.csdn.net/enuola/article/details/8639404  最近做一个项目,需要用到UITableView异步加载图片的例子,看到网上有一个E ...

  9. ios开发 UITableView with xib 以及自定义TableViewCell

    原文网址:http://blog.csdn.net/m_changgong/article/details/8115137 作者:张燕广 1.创建一个Single View Application工程 ...

  10. iOS开发--UITableView

    -.建立 UITableView DataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)]; [DataTa ...

最新文章

  1. Linux 最常用命令(简单易学,但能解决95%以上的问题)
  2. SpringMVC 如何实现将消息的websocket
  3. android proguard 第三方jar,Android Studio代码混淆-第三方jar混淆汇总(持续更新)
  4. 信用评分卡—信贷准入A卡(逻辑回归)
  5. windows下的C/C++精确计时
  6. 简单的一个用javascript做的'省市区'三级联动效果
  7. NET中解决KafKa多线程发送多主题的问题
  8. ajax前端实时获取数据
  9. pycharm通过pytest运行报错:No test were found 解决
  10. Pycharm 安装
  11. 用面对对象方式定tab标签
  12. 手把手分析 mfc 程序创建 代码执行流程
  13. ETL数据清洗工具总结
  14. 有道词典与奇迹背单词生词本同步
  15. beego 静态文件处理
  16. SUBTYPE正规化数据类型
  17. LRC (Lyric) 字幕
  18. 简单翻译工具--必应词典第三方api使用方法
  19. 41岁职场中年人深度劝告:一定要从小公司往大公司走
  20. 创意名片大全:一组精美的折叠效果名片设计

热门文章

  1. 物联网关键技术————传感器技术
  2. 冲向2021 荣耀“无限”创新
  3. Java 小数保留小数位数的方法
  4. 泰岳区块链-隐私计算之差分隐私算法概念了解
  5. day23_1-re模块之转义字符、分组、方法
  6. 设随机过程{X(t)=Acos(ωt+Θ),t∈(一∞,+∞)},其中A,ω,Θ为相互独立的实随机变量,其中A的均值为2,方差为4,且Θ~U(-π,π),ω~U(-5,5),试问X(t)是否为平稳过程
  7. Mach-O入门理解
  8. 腾讯TEG一面(电话面试)
  9. 孙卫琴——缅怀张孝祥老师(原文)
  10. 【※taskmgr.exe进程知识详解※电脑知识】