Objective-C UI之UITableView详解

UITableView在IOS开发中占据非常重要的位置,必须熟练掌握。

学习UITableView之前,先了解一下一些基本概念:

  • UITableView继承于UIScrollView,是可以进行垂直滚动的控件
  • UITableView的每一条数据对应的单元格叫做Cell,是UITableViewCell的一个对象,继承于UIView
  • UITableView可以分区显示,每一个分区称为section,每一行称为row,编号都从0开始
  • 系统提供了一个类来整合section和row,叫做NSIndexPath

从上面可以了解到,section和row代表一个UITableViewCell在UITableView上的位置

下面,我们创建一个UITableView:

//style是一个UITableViewStyle类型的参数,是一个枚举类型,包含UITableViewStylePlain,UITableViewStyleGrouped
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];

[self.view addSubview:tableView];

下面是UITableView的常用属性:

rowHeight 行高
separatorStyle 分隔线样式
separatorColor 分隔线颜色
tableHeaderView UITableView的置顶视图
tableFooterView UITableView置底视图

UITableView基础

UITableView中有两个重要的属性:dataSource(遵循UITableViewDataSource协议)和delegate(遵循UITableViewDelegate协议)

其中dataSource是和显示数据相关的代理,delegate是和视图操作相关的代理

UITableViewDataSource协议中有两个必须实现的协议方法:


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

UITableView每个分区包含的行数

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

每一行要显示的Cell

第一个方法可以根据给出的参数section不同返回不同的行数

第二个方法:tableView每次要显示一个Cell都会调用这个方法获取

UITableView的每一个单元格是UITableViewCell类的对象,默认提供了三个视图属性:

  1. 图片视图:UIImageView *imageView
  2. 标题视图:UILabel *textLabel
  3. 副标题视图:UILabel *detailTextLabel

下面是返回Cell的例子:(没有使用registerClass注册的情况)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"cell";

    //通过标识符,在tableView的重用池中找到可用的Cell(在重用池内部其实是一个可变的集合)
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];

    //如果重用池中没有这个标识符对应的cell,则创建一个新的,并且设置标识符
    if (!cell) {
        //代码块内只做Cell样式的处理,不做数据设置
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:cellID];
    }

    //对Cell做数据设置
    [cell.textLabel setText:@"标题"];
    [cell.detailTextLabel setText:@"描述:这是小标题"];

    return cell;
}

UITableView有一个重用池机制管理Cell,目的是使用尽可能少的Cell显示所有的数据

UITableView重用Cell的流程

  1. 当一个Cell被滑出屏幕,这个Cell会被系统放到相应的重用池中
  2. 当tableView需要显示一个Cell,会先去重用池中尝试获取一个Cell
  3. 如果重用池没有Cell,就会创建一个Cell
  4. 取得Cell之后会重新赋值进行使用

在创建UITableView之后,需要注册一个Cell类,当重用池中没有Cell的时候,系统可以自动创建Cell。相关方法:

[tableView registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier];(可以使用不同identifier进行多次注册)

系统提供了一个获取重用池中Cell的方法(需要一个重用标识):

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;

UITableView的常用协议方法

  • UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

UITableView分区个数

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

分区的顶部标题

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section

分区的底部标题

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView

UITableView右侧的索引录
  • UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

告诉delegate选中了一个Cell

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

每一行的高度

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

每一个分区的顶部高度

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

每一个分区的顶部自定义视图

UITableView编辑

流程:

  1. 让tableView处于编辑状态:[tableView setEditing:(BOOL)editing animated:(BOOL)animated];
  2. 确定Cell是否处于编辑状态:

    //重写UITableViewDataSource的协议方法,根据indexPath决定哪些Cell处于编辑状态,返回YES是可编辑,NO为不可编辑
    - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
  3. 设定Cell的编辑样式(删除、添加):

    //重写UITableViewDelegate的协议方法,根据indexPath可以决定Cell的编辑样式,是添加UITableViewCellEditingStyleInsert还是删除UITableViewCellEditingStyleDelete,还是不进行编辑UITableViewCellEditingStyleNone
    - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
  4. 编辑状态进行提交:

    //重写UITableViewDataSource协议方法,根据editingStyle删除indexPath位置的Cell,还是在indexPath处插入Cell,修改数据源
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
    

注意:编辑结束后,由于numberOfRowInSection这个协议方法只在tableView添加到父视图的时候调用一次,而且table上的数据都是由数组提供,因此,需要先改变数组中的数据,然后让table的协议重新调用进行重新赋值

即先修改数据源,在刷新table(使用[table reloadData]方法刷新)

UITableView移动

  1. 实现协议,告诉tableView是否能够移动:

    //返回YES允许移动
    - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
  2. 移动:

    //修改数据源,再进行[tableView reloadData]更新tableView视图数据
    - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath

UITableViewCell

1.自定义Cell

  1. 创建一个类继承于UITableViewCell
  2. 实现UITableViewCell的初始化方法:- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
  3. 确保所有的添加的子视图都在自定义Cell的初始化方法中创建,避免子视图的重复创建
  4. 在Cell的子视图创建成功后,将子视图设置为属性,便于在UITableView的协议中给自定义视图赋值

一般而言,Cell在创建的时候的frame大小是(0,0,320,44),而我们设定的Cell的高度一般会大于44。因此:在自定义Cell中创建子视图的frame为CGRectZero。在Cell添加到tableView上的时候才给子视图设置frame,Cell添加到tableView的时候大小已经更改为tableView设定的大小,所以在自定义Cell的方法layoutSubviews中设置子视图的frame

2.Model的使用

Model类的作用主要是为我们提供数据,一般我们的数据都是存放在数组和字典中,OC中的KVC就是帮助我们将字典转换为Model类而存在的

使用步骤:

  1. 创建一个Model类继承于NSObject
  2. 添加和字典中对应的属性,属性名要和字典key值相同,除系统关键字外
  3. 在视图控制器中将字典通过KVC为Model赋值
  4. 将Model对象添加到数组中并刷新tableView

注意:Model类要重写-(void)setValue:(id)value forUndefinedKey:(NSString *)key,防止找不到和key值相同的属性时,会crash,当key值为系统关键字,可以在方法里面为对应的属性(属性名和系统关键字不冲突)赋值,比如_id = value;

3.多种Cell混合使用

不同的Cell需要使用不同的重用标识符来进行区分,而重用标识符的区分需要根据不同的情况来区分,比如:

  • Model属性区分(不同的数据内容,比如数据中有type字段,0代表文字类型,1代表图片类型)
  • 固定的行显示的Cell类型不一样

4.自适应高度

  1. 文本自适应高度:

    //获得字体样式属性
    NSDictionary *att = @{NSFontAttributeName:[UIFont systemFontOfSize:18.0]};
    //根据字体样式属性获得高度
    CGRect rect = [string boundingRectWithSize:CGSizeMake(300,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:att context:nil];
    //重新设置显示文本控件的frame
    [self.label setFrame:CGRectMake(0,0,300,rect.size.height)];
    
    //我们可以定义一个类专门用来计算文本高度,这样可以使用时直接调用
  2. Cell自适应高度:

    通过协议方法- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath设定Cell的高度
    
    在自定义Cell中的layoutSubviews方法中设定子视图的高度


转载请注明:作者SmithJackyson

时间: 2024-12-25 06:59:00

Objective-C UI之UITableView详解的相关文章

UITableView 详解 ()

(原本取至D了个L微信公众号) UITableView 详解 一.建立 UITableView DataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)]; [DataTable setDelegate:self]; [DataTable setDataSource:self]; [self.view addSubview:DataTable]; [DataTable release]; 二.UITable

iOS开发——UI篇&ScrollView详解

ScrollView详解 创建方式 1:StoryBoard/Xib 这里StoarBoard就不多说,直接拖就可以,说太多没意思,如果连这个都不会我只能先给你跪了! 2:代码: CGRect bounds = [ [ UIScreen mainScreen ] applicationFrame ] ; UIScrollView* scrollView = [ [UIScrollView alloc ] initWithFrame:bounds ]; 当你创建完滚动视图后,你可以将另一个视图的内

android自定义UI模板图文详解

不知道大家在实际开发中有没有自定义过UI模板?今天花时间研究了一下android中自定义UI模板,与大家分享一下. 每个设计良好的App都是自定义标题栏,在自定义标题栏的过程中大部分人可能都是自定义一个标题的xml文件,然后在需要的地方直接通过include来引用,这比起在每个布局文件中写标题栏已经进化很多了,但仍然不是最简单有效的方法,我们为什么不能自定义一个标题控件呢?今天就带大家自己做一个标题栏控件.效果图如下: 开始啦: 第一步:自定义xml属性 新建一个android项目,在value

【转】UITableView详解(UITableViewCell

原文网址:http://www.kancloud.cn/digest/ios-1/107420 上一节中,我们定义的cell比较单一,只是单调的输入文本和插入图片,但是在实际开发中,有的cell上面有按钮,有的cell上面有滑动控件,有的cell上面有开关选项等等,具体参加下面2个图的对比:          @我们可以通过2种方式来实现自定义,一是利用系统的UITableViewCell(但不推荐,因为开发效率不高),举例:还是在这个关键方法中 (UITableViewCell)tableVi

IOS控件UITableView详解

首选创建一个新的项目,并添加一个MainViewController的Class文件 打开MainViewController.h文件 [cpp] view plaincopy @interface MainViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> @property (nonatomic, retain) NSArray *dataList; @property (nonatomi

Android UI性能优化详解

设计师,开发人员,需求研究和测试都会影响到一个app最后的UI展示,所有人都很乐于去建议app应该怎么去展示UI.UI也是app和用户打交道的部分,直接对用户形成品牌意识,需要仔细的设计.无论你的app UI是简单还是复杂,重要的是性能一定要好. UI性能测试 性能优化都需要有一个目标,UI的性能优化也是一样.你可能会觉得“我的app加载很快”很重要,但我们还需要了解终端用户的期望,是否可以去量化这些期望呢?我们可以从人机交互心理学的角度来考虑这个问题.研究表明,0-100毫秒以内的延迟对人来说

UITableView详解

一.建立 UITableView DataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)]; [DataTable setDelegate:self]; [DataTable setDataSource:self]; [self.view addSubview:DataTable]; [DataTable release]; 二.UITableView各Method说明 //Section总数 - (NS

【IOS 开发】基本 UI 控件详解 (UIDatePicker | UIPickerView | UIStepper | UIWebView | UIToolBar )

转载注明出处 : http://blog.csdn.net/shulianghan/article/details/50348982 一. 日期选择器 (UIDatePicker) UIDatePicker 属性截图 : 1. UIDatePicker 控件属性 (1) Mode 属性 Mode 属性 : 用于设置 UIDatePicker 模式; -- Date 属性值 : 显示日期, 不显示时间; -- Time 属性值 : 显示时间, 不显示日期; -- Date and Time 属性值

UI Recorder 功能详解

前言: UI Recorder安装教程见:UI Recorder 安装教程(一).UI Recorder 安装教程(二) 本次着重介绍UI Recorder录制过程中的功能按钮:添加悬停,添加断言,使用变量,执行JS,添加延迟,脚本跳转,结束录制.如下图所示: 1.属性开关 进入录制页面后,属性开关全部为默认开启状态,因此在你点击任意DOM时,DomPath会自动选择属性并展示.如下图所示: 鼠标点击页面DOM"Email:",DomPath展示为://td[text()="