4、iOS 开发之 UITableView

一、UITableView的创建

  • 表格控件在创建时必须指定样式,只能使用以下实例化方法
[[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];

UITableView的两种样式

 1> UITableViewStylePlain
 2> UITableViewStyleGrouped

2.UITableView的常见属性

// 头部视图(广告)
@property (nonatomic, retain) UIView *tableHeaderView;
// 显示加载的状态
@property (nonatomic, retain) UIView *tableFooterView;
// 每行的高度
@property (nonatomic) CGFloat rowHeight;
// 组头部高度(QQ好友列表)
@property (nonatomic) CGFloat sectionHeaderHeight;
// 组尾部高度
@property (nonatomic) CGFloat sectionFooterHeight;

3.常见的方法

// 用于从缓存池中取出可用的cell
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;

二、UITableView展示数据

  • UITableView展示数据需要数据源datasource
  • 遵守数据源协议 UITableViewDataSource,并实现数据源的方法

1.遵守数据源协议

<UITableViewDataSource>
self.tableView.dataSource = self;

2.实现数据源方法

// 一共有多少组数据
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
// 每一组有多少行数据
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
// 每一行显示什么内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
// 每行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
// 选中某一行的数据
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
// 组头部标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
// 组尾部标题
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
// 右值索引列表
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;
// 组头部视图
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
// 组尾部视图
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
// 组头高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
// 组尾部高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

三、UITableViewCell的创建

1.cell的常见属性

// 图标
@property (nonatomic, readonly, retain) UIImageView *imageView;
// 标题
@property (nonatomic, readonly, retain) UILabel     *textLabel;
// 详细标题
@property (nonatomic, readonly, retain) UILabel     *detailTextLabel;
// 内容视图,是包含以上3个视图的
@property (nonatomic, readonly, retain) UIView      *contentView;
// 右边的入口视图
@property (nonatomic, retain) UIView                *accessoryView;

2.创建cell的方法

1>

// cell是通过手写代码创建的,才会调用这个方法来初始化cell
[[UITableViewCell alloc] initWithStyle:<#(UITableViewCellStyle)#> reuseIdentifier:<#(NSString *)#>];

UITableviewCellStyle属性决定使用contentView的哪些子视图,以及这些子视图的位置

UITableViewCellStyleDefault // 标题+图像
UITableviewCellStyleSubtitle // 标题+明细+图像
UITableViewCellStyleValue1   // 标题+明细+图像
UITableviewCellStyleValue2   // 标题+明细
reuseIdentifier:用于cell循环利用的标示ID

2>

// cell是通过storyboard或则xib实现的,就会调用这个方法来初始化cell
- (void)awakeFromNib
{}

3>

// 在这方法中设置子控件的frame
- (void)layoutSubViews
{}

3.Cell重用的原理

1> 当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,然后返回给UITableView,重新显示到窗口中,从而避免创建新对象

2> 还有一个非常重要的问题:有时候需要自定义UITableViewCell(用一个子类继承UITableViewCell),而且每一行用的不一定是同一种UITableViewCell,所以一个UITableView可能拥有不同类型的UITableViewCell,对象池中也会有很多不同类型的UITableViewCell,那么UITableView在重用UITableViewCell时可能会得到错误类型的UITableViewCell

解决方案:

UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化一个UITableViewCell对象

4.Cell的重用代码

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1.定义一个cell的标识
    static NSString *ID = @"mjcell";

    // 2.从缓存池中取出cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    // 3.如果缓存池中没有cell
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }

    // 4.设置cell的属性...

    return cell;
}

四、cell的自定义实现

1.xib实现UITableViewCell (cell的高度一致)

1> 新建一个xib文件描述一个View的内部结构(假设叫WBTgCell.xib)
2> 新建一个自定义的类,类名和xib文件名保持一致 WBTgCell
3> 将xib中的控件和自定义的.m文件进行连线,并指定可重用的标示符
4> 提供一个类方法返回一个创建好的自定义的view(屏蔽xib的加载过程)
5> 提供一个模型属性接受外界传来的模型数据
6> 重写模型属性的setter方法,在setter方法中将模型数据展示到对应的子控件上

2.通过代码自定义cell(cell的高度不一致)

1> 新建一个继承自UITableviewCell的类
2> 重写initWithStyle:reuseIdentifier:方法
    *添加所有需要显示的子控件(不需要设置子控件的数据和frame,子控件要添加到contentView中)
    *进行子控件一次性的属性设置(有些属性只需要设置一次,比如字体、固定的图片)
3> 提供2个模型
    *数据模型:存放文字数据\图片数据
    *frame模型:存放数据模型\所有子控件的frame\cell的高度
4> cell拥有一个frame模型(不要直接拥有数据模型)
5> 重写frame模型属性的setter方法:在这个方法中设置子控件的显示数据和frame
6> frame模型数据的初始化已经采取懒加载的方法(每个cell对应的frame模型数据只加载1次)

五、静态单元格

1> 通过没storyboard设置tableview的content属性,static是静态单元格,dynamic是动态添加的

2> 静态单元格适用于tableview里面的cell内容和现实都是固定的,后续不需要更改cell内部的内容

3> 如果tableview中显示的内容需要改变的就不能用静态单元格

六、动态单元格

应用程序管理

1>cell重用容易出现从缓存池中取出来的cell 可能是之前更改过状态的cell,所以在重用的时候必须覆盖所有cell中子控件的状态。
2>当cell从storyboard中tableviewcontroller中唯一标示中取出来的时候,控制器可以不做初始化操作,if(cell == nil){};因为storyboard中确实已经存在了cell了
3>storyBoard中自定义cell的时候,可以创建多个cell的模型,然后根据唯一标示可以取出相应的cell
4>按钮能不能用取决于当前cell有没有下载

补充:

1、字符串的尺寸

// NSString字符串中对象方法:
- (CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize
{
    NSDictionary *attrs = @{NSFontAttributeName : font};
    return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
}

2、图片的随意不变形(直接Xcode中设置图片就行)

+ (UIImage *)resizableImage:(NSString *)name
{
    UIImage *normal = [UIImage imageNamed:name];
    CGFloat w = normal.size.width * 0.5;
    CGFloat h = normal.size.height * 0.5;
    return [normal resizableImageWithCapInsets:UIEdgeInsetsMake(h, w, h, w)];
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-09 04:10:05

4、iOS 开发之 UITableView的相关文章

iOS开发之UITableView全面解析

在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,类似于微信.QQ.新浪微博等软件基本上随处都是UITableView.当然它的广泛使用自然离不开它强大的功能,今天这篇文章将针对UITableView重点展开讨论.今天的主要内容包括: 1.基本介绍 2.数据源 3.代理 4.性能优化 5.UITableViewCell 6.常用操作 7.UITableViewController 8.MVC模式   基本介绍 UITableView有两种风

iOS开发之UITableView的使用

这一篇记录的是iOS开发中UITableView的使用,iOS中的UITableView跟Android中的ListView特别相似,以下用一个Demo来说明: 1.Xcode中新建projectTestSimpleTableViewproject 2.在Main.storyboard中拖入一个UITableView控件 3.在ViewController.h文件里,实现UITableViewDelegate和UITableViewDataSource协议 这里须要说下的是.为了给UITable

IOS开发之UITableView使用大全。

前言: UITableView是ios开发中最常用的控件之一,几乎所有的应用都要用到,tableview继承UIScrollView,因此它不仅可以显示多行数据,而且具有scrollview的一些操作功能,比如滑动,自动偏移等等,因此非常强大. 而且tableview采用了数据源模式,因此只需要更改它的数据源,即可实现tableview显示数据的变化,而且tableviewcell还具有复用性. 所以tableview是一个在显示大量数据时及其好的选择. 1. tableview采用的是代理模式

iOS开发之UITableView使用总结

什么是UITableView 在众多移动应用中,能看到各式各样的表格数据 在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView UITableView继承自UIScrollView,因此支持垂直滚动,而且性能极佳 UITableView的两种样式 UITableViewStylePlain UITableViewStyleGrouped tableView展示数据的过程 1.调用数据源的下面方法得知一共有多少组数据 - (NSInteger)numberOfSections

iOS开发之UITableView及cell重用

1.UITanleview有的两种风格 一种是Plain,一种是Grouped,可以从这里设置风格: 他们样式分别如下: Plain: Grouped: 2.tableView展示数据的过程: (1)首先,控制器要遵守UITableViewDataSource协议 @interface ViewController () <UITableViewDataSource> (2)调用数据源的下面方法得知一共有多少组数据 - (NSInteger)numberOfSectionsInTableVie

IOS开发之UITableView的奇技

作者:Biaoac age:保密 sex:直男 性格:低调沉稳,乖张内涵 博客背景:之前一直在使用UITableView,但是一直都只是初识,后来在不断的使用中找到了很多之前没有在意的东西,遂整理出来,当然,有很多还是看别人的博客中提到的点,我把他重踩一遍: 1.点击的时候显示选中状态,但状态一直村在,必须在点击下一个的时候取消选中状态 点击cell的时候调用 - (void)tableView:(UITableView )tableView didSelectRowAtIndexPath:(N

IOS开发之UITableView

UITableView就相当于android中的listview,在这里先介绍一个简单的UItableView的用法,因为我也是刚学.而且也遇到了一些问题.直接上代码吧 这是ViewController.h  #import <UIKit/UIKit.h> @interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> @property (nonatomic,retai

iOS开发之UITableView的滚动优化以及隐藏特性的使用

郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 如果文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额随意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源码下载:点我传送 游戏官方下载:http://dwz.cn/RwTjl 游戏视频预览:http://dwz.cn/RzHHd 游戏开发博客:http://dwz.cn/RzJzI 游戏源码传送:http://dwz.cn/Nret1 影响 UITableView 滚动的流畅性的原因 1. 在代理方法中做了过多的计算占用了 UI

李洪强iOS开发之RunLoop的原理和核心机制

李洪强iOS开发之RunLoop的原理和核心机制 搞iOS之后一直没有深入研究过RunLoop,非常的惭愧.刚好前一阵子负责性能优化项目,需要利用RunLoop做性能优化和性能检测,趁着这个机会深入研究了RunLoop的原理和特性. RunLoop的定义 当有持续的异步任务需求时,我们会创建一个独立的生命周期可控的线程.RunLoop就是控制线程生命周期并接收事件进行处理的机制. RunLoop是iOS事件响应与任务处理最核心的机制,它贯穿iOS整个系统. Foundation: NSRunLo