首页 > 代码库 > UI基础之UITableView的基本使用

UI基础之UITableView的基本使用

UITableView控件

1,基本使用(required)

UITableView有两种样式:grouped/plain 组/单行

UITableView需要?一个数据源(dataSource)来显示数据
UITableView会向数据源查询一共有多少行数据以及每?行显示什么数据等

没有设置数据源的UITableView只是个空壳

凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源  

展示数据的过程:

(1)调用数据源的下面?法得知?一共有多少组数据
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

(2)调用数据源的下面?法得知每一组有多少行数据
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

(3)调?数据源的下??法得知每??显示什么内容

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

2,UITableView的常用属性

(1)设置分割样式和边距(tableview.separatorStyle),这是个枚举类型

 separatorInset

(2)设置分割线的颜色,可以直接使用系统给出的颜色,如果系统给定的颜色不能满足需求时,也可以自定义。

  补充:颜色分为24位和32位的,如下

  24bit颜色

     R 8bit 0 ~ 255

     G 8bit 0 ~ 255

     B 8bit 0 ~ 255

     32bit颜色

     A 8bit 0 ~ 255(tou)

     R 8bit

     G 8bit

     B 8bit     

     #ff ff ff 白色

     #00 00 00 黑色

     #ff 00 00 红色

     #255 00 00

 设置为自定义颜色的实例:tableview.separatorColor = [UIColorcolorWithRed:0/255.0green:255/255.0blue:0/255.0alpha:255/255.0];

 //接收的参数是颜色的比例值

 (3)设置顶部和底部视图

tableview.tableHeaderView   //顶部

tableview.tableFooterView    //底部

4)设置cell的高度

tableView.rowHeight  // cell高度

5)每一组的头部、尾部高度

sectionHeaderHeight

sectionFooterHeight

6)背景颜色两个属性

backgroundView(优先级高)

backgroundColor(优先级低)

默认tableView设置颜色会被它上面cell挡住,可以设置cell的透明度

7)刷新数据

reloadData(整个tableView的数据)

- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation

(刷新某一个组某一行的数据)

3,UITableViewCell的常用属性

 UITableViewCell内部用一个contentView属性在contentview中默认有三个子视图:

第2个是UILabel(通过UITableViewCell的textLabel和detailTextLabel属性访问)

第3个是UIImageView(通过UITableViewCell的imageView属性访问)

 UITableViewCell还有?个UITableViewCellStyle属性,?于决定使用contentView的哪些子视图,以及这些子视图在contentView中的位置 

1)辅助视图

1)设置cell的辅助视图,设置cell.accessoryView(系统提供了枚举型,也可以自定义@父类指针指向子类对象);

2,设置cell的背景颜色两种属性

backgroundColor/ backgroundView

选中状态的颜色

selectedbackgroundView(color)

4 常用的数据源方法和代理方法

数据源方法

 代理方法:

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

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

 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

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

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

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

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

5,UITableViewCell的性能问题

 问题cell的工作:在程序执行的时候,能看到多少条,它就创建多少条数据,如果视图滚动那么再创建新显示的内容。(系统自动调用)。即当一个cell出现在视野范围内的时候,就会调用创建一个cell。这样

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

注意点:对象池中也会有很多不同类型的 UITableViewCell,那么UITableView在重?用UITableViewCell时可能会得到错误类型的 UITableViewCell

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

缓存优化的思路:

(1)先去缓存池中查找是否有满足条件的cell,若有那就直接拿来

(2)若没有,就自己创建一个cell

(3)创建cell,并且设置一个唯一的标记(把属于“”的给盖个章)

(4)给cell设置数据

注意点:

定义变量用来保存重用标记的值,这里不推荐使用宏(#define来处理),因为该变量只在这个作用域的内部使用,且如果使用宏定义的话,定义和使用位置太分散,不利于阅读程序。由于其值不变,没有必要每次都开辟一次,所以用static定义为一个静态变量。

6,刷新数据的两个步骤:

 

   1)修改模型

 

   2)刷新表格数据(可以全部刷新,也可以刷新指定的行)

 

代码案例:

数据模型:

#import <Foundation/Foundation.h>@interface LLHeroList : NSObject@property (nonatomic, copy) NSString *icon;@property (nonatomic, copy) NSString *intro;@property (nonatomic, copy) NSString *name;- (instancetype)initWithDic:(NSDictionary *)dic;+ (instancetype)heroListWithDic:(NSDictionary *)dic;+ (NSMutableArray *)heroesList;@end
#import "LLHeroList.h"@implementation LLHeroList- (instancetype)initWithDic:(NSDictionary *)dic{    if (self = [super init]) {        [self setValuesForKeysWithDictionary:dic];    }    return self;}+ (instancetype)heroListWithDic:(NSDictionary *)dic{    return [[self alloc] initWithDic:dic];}+ (NSMutableArray *)heroesList{    NSString *path = [[NSBundle mainBundle] pathForResource:@"heros" ofType:@"plist"];    NSArray *dicArr = [NSArray arrayWithContentsOfFile:path];        NSMutableArray *tmpArr = [[NSMutableArray alloc] initWithCapacity:dicArr.count];    for (NSDictionary *dic in dicArr) {                LLHeroList *hero = [LLHeroList heroListWithDic:dic];                [tmpArr addObject:hero];    }    return tmpArr;}@end

controller:

#import "ViewController.h"#import "LLHeroList.h"@interface ViewController ()<UITableViewDataSource, UITableViewDelegate, UIAlertViewDelegate, UIActionSheetDelegate>@property (nonatomic, strong) NSMutableArray *heroes;@property (nonatomic, weak) UITableView *tableView;@end@implementation ViewController- (NSMutableArray *)heroes{    if (!_heroes) {                _heroes = [LLHeroList heroesList];    }    return _heroes;}- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.        [self loadTableView];}- (void)loadTableView{    UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];    [self.view addSubview:tableView];    self.tableView = tableView;        self.tableView.dataSource = self;    self.tableView.rowHeight = 60;        // tableView的代理    self.tableView.delegate = self;        // tableView分割线颜色设置:    self.tableView.separatorColor = [UIColor colorWithRed:0/255.0 green:255/255.0 blue:0/255.0 alpha:1];    // 设置分割线的内边距    self.tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);}#pragma mark - 数据源方法- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return self.heroes.count;    }- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static NSString *ID = @"hero";    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:ID];        if (!cell) {                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];    }        LLHeroList *hero = self.heroes[indexPath.row];    cell.imageView.image = [UIImage imageNamed:hero.icon];    cell.textLabel.text = hero.name;    cell.detailTextLabel.text = hero.intro;        // 给cell添加辅助按钮    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;        // 给cell添加背景图片    cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"buttonorange"]];    // 设置cell选中的颜色    cell.selectedBackgroundView =  [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"buttonred"]];        return cell;}#pragma mark - tableView的代理方法- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{//    // 1,创建一个alertView对象//    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"英雄展示" message:nil delegate:self cancelButtonTitle:@"cancle" otherButtonTitles:@"ok", nil];//    //    // 2,设置alertView的样式(3中样式)//    alertView.alertViewStyle = UIAlertViewStylePlainTextInput;//    //    // 3,设置alertView文本输入框展示的内容//    [alertView textFieldAtIndex:0].text = [self.heroes[indexPath.row] name];//    //    // 4,给alertView的代理方法传递当前选中行的行号//    alertView.tag = indexPath.row;//    [alertView show];        UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"英雄展示" delegate:self cancelButtonTitle:@"cancel" destructiveButtonTitle:@"删除英雄" otherButtonTitles:@"ok" ,nil];    sheet.tag = indexPath.row;        [sheet showInView:[[UIView alloc] init]];}#pragma mark - alertView的代理方法- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{    if (buttonIndex == 0) return;        // 修改数据模型    LLHeroList *hero = self.heroes[alertView.tag];    hero.name = [alertView textFieldAtIndex:0].text;        // 刷新表格//    // 全部刷新//    [self.tableView reloadData];    // 局部刷新    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:alertView.tag inSection:0];    [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];    }#pragma mark - actionSheet代理方法- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{    if (buttonIndex == 0) {                [self.heroes removeObjectAtIndex:actionSheet.tag];        [self.tableView reloadData];    }}@end

效果:

 

 

UI基础之UITableView的基本使用