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

效果:

原文地址:https://www.cnblogs.com/-boy/p/4121984.html