UItableView系列——数据源

原创 2015年11月19日 14:53:49

由于iOS是遵循MVC模式设计的,很多操作都是通过代理和外界沟通的,但对于数据源控件除了代理还有一个数据源属性,通过它和外界进行数据交互。 对于UITableView设置完dataSource后需要实现UITableViewDataSource协议,在这个协议中定义了多种 数据操作方法,下面通过创建一个简单的联系人管理进行演示:

首先我们需要创建一个联系人模型KCContact,KCContact.h代码如下:

//
//  Contact.h
//  UITableView
//
//  Created by Kenshin Cui on 14-3-1.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface KCContact : NSObject

#pragma mark 姓
@property (nonatomic,copy) NSString *firstName;
#pragma mark 名
@property (nonatomic,copy) NSString *lastName;
#pragma mark 手机号码
@property (nonatomic,copy) NSString *phoneNumber;

#pragma mark 带参数的构造函数
-(KCContact *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber;

#pragma mark 取得姓名
-(NSString *)getName;


#pragma mark 带参数的静态对象初始化方法
+(KCContact *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber;
@end

KCContact.m代码如下:

//
//  Contact.m
//  UITableView
//
//  Created by Kenshin Cui on 14-3-1.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCContact.h"

@implementation KCContact

-(KCContact *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber{
    if(self=[super init]){
        self.firstName=firstName;
        self.lastName=lastName;
        self.phoneNumber=phoneNumber;
    }
    return self;
}

-(NSString *)getName{
    return [NSString stringWithFormat:@"%@ %@",_lastName,_firstName];
}

+(KCContact *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber{
    KCContact *contact1=[[KCContact alloc]initWithFirstName:firstName andLastName:lastName andPhoneNumber:phoneNumber];
    return contact1;
}

@end

为了演示分组显示我们不妨将一组数据也抽象成模型KCContactGroup,KCContactGroup.h代码如下:

//
//  KCContactGroup.h
//  UITableView
//
//  Created by Kenshin Cui on 14-3-1.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "KCContact.h"

@interface KCContactGroup : NSObject

#pragma mark 组名
@property (nonatomic,copy) NSString *name;

#pragma mark 分组描述
@property (nonatomic,copy) NSString *detail;

#pragma mark 联系人
@property (nonatomic,strong) NSMutableArray *contacts;

#pragma mark 带参数个构造函数
-(KCContactGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts;

#pragma mark 静态初始化方法
+(KCContactGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts;

@end
KCContactGroup.m代码如下:

//
//  KCContactGroup.m
//  UITableView
//
//  Created by Kenshin Cui on 14-3-1.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCContactGroup.h"

@implementation KCContactGroup


-(KCContactGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts{
    if (self=[super init]) {
        self.name=name;
        self.detail=detail;
        self.contacts=contacts;
    }
    return self;
}

+(KCContactGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts{
    KCContactGroup *group1=[[KCContactGroup alloc]initWithName:name andDetail:detail andContacts:contacts];
    return group1;
}
@end

然后在viewDidLoad方法中创建一些模拟数据同时实现数据源协议方法,KCMainViewController.m代码如下:

//
//  KCMainViewController.m
//  UITableView
//
//  Created by Kenshin Cui on 14-3-1.
//  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
//

#import "KCMainViewController.h"
#import "KCContact.h"
#import "KCContactGroup.h"

@interface KCMainViewController ()<UITableViewDataSource>{
    UITableView *_tableView;
    NSMutableArray *_contacts;//联系人模型
}

@end

@implementation KCMainViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //初始化数据
    [self initData];
    
    //创建一个分组样式的UITableView
    _tableView=[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
    
    //设置数据源,注意必须实现对应的UITableViewDataSource协议
    _tableView.dataSource=self;
    
    [self.view addSubview:_tableView];
}

#pragma mark 加载数据
-(void)initData{
    _contacts=[[NSMutableArray alloc]init];
    
    KCContact *contact1=[KCContact initWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"];
    KCContact *contact2=[KCContact initWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"];
    KCContactGroup *group1=[KCContactGroup initWithName:@"C" andDetail:@"With names beginning with C" andContacts:[NSMutableArray arrayWithObjects:contact1,contact2, nil]];
    [_contacts addObject:group1];
    

    
    KCContact *contact3=[KCContact initWithFirstName:@"Lee" andLastName:@"Terry" andPhoneNumber:@"18500131238"];
    KCContact *contact4=[KCContact initWithFirstName:@"Lee" andLastName:@"Jack" andPhoneNumber:@"18500131239"];
    KCContact *contact5=[KCContact initWithFirstName:@"Lee" andLastName:@"Rose" andPhoneNumber:@"18500131240"];
    KCContactGroup *group2=[KCContactGroup initWithName:@"L" andDetail:@"With names beginning with L" andContacts:[NSMutableArray arrayWithObjects:contact3,contact4,contact5, nil]];
    [_contacts addObject:group2];
    
    
    
    KCContact *contact6=[KCContact initWithFirstName:@"Sun" andLastName:@"Kaoru" andPhoneNumber:@"18500131235"];
    KCContact *contact7=[KCContact initWithFirstName:@"Sun" andLastName:@"Rosa" andPhoneNumber:@"18500131236"];

    KCContactGroup *group3=[KCContactGroup initWithName:@"S" andDetail:@"With names beginning with S" andContacts:[NSMutableArray arrayWithObjects:contact6,contact7, nil]];
    [_contacts addObject:group3];
    
    
    KCContact *contact8=[KCContact initWithFirstName:@"Wang" andLastName:@"Stephone" andPhoneNumber:@"18500131241"];
    KCContact *contact9=[KCContact initWithFirstName:@"Wang" andLastName:@"Lucy" andPhoneNumber:@"18500131242"];
    KCContact *contact10=[KCContact initWithFirstName:@"Wang" andLastName:@"Lily" andPhoneNumber:@"18500131243"];
    KCContact *contact11=[KCContact initWithFirstName:@"Wang" andLastName:@"Emily" andPhoneNumber:@"18500131244"];
    KCContact *contact12=[KCContact initWithFirstName:@"Wang" andLastName:@"Andy" andPhoneNumber:@"18500131245"];
    KCContactGroup *group4=[KCContactGroup initWithName:@"W" andDetail:@"With names beginning with W" andContacts:[NSMutableArray arrayWithObjects:contact8,contact9,contact10,contact11,contact12, nil]];
    [_contacts addObject:group4];
    
    
    KCContact *contact13=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joy" andPhoneNumber:@"18500131246"];
    KCContact *contact14=[KCContact initWithFirstName:@"Zhang" andLastName:@"Vivan" andPhoneNumber:@"18500131247"];
    KCContact *contact15=[KCContact initWithFirstName:@"Zhang" andLastName:@"Joyse" andPhoneNumber:@"18500131248"];
    KCContactGroup *group5=[KCContactGroup initWithName:@"Z" andDetail:@"With names beginning with Z" andContacts:[NSMutableArray arrayWithObjects:contact13,contact14,contact15, nil]];
    [_contacts addObject:group5];

}

#pragma mark - 数据源方法
#pragma mark 返回分组数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    NSLog(@"计算分组数");
    return _contacts.count;
}

#pragma mark 返回每组行数
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    NSLog(@"计算每组(组%i)行数",section);
    KCContactGroup *group1=_contacts[section];
    return group1.contacts.count;
}

#pragma mark返回每行的单元格
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    //NSIndexPath是一个结构体,记录了组和行信息
    NSLog(@"生成单元格(组:%i,行%i)",indexPath.section,indexPath.row);
    KCContactGroup *group=_contacts[indexPath.section];
    KCContact *contact=group.contacts[indexPath.row];
    UITableViewCell *cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
    cell.textLabel.text=[contact getName];
    cell.detailTextLabel.text=contact.phoneNumber;
    return cell;
}

#pragma mark 返回每组头标题名称
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    NSLog(@"生成组(组%i)名称",section);
    KCContactGroup *group=_contacts[section];
    return group.name;
}

#pragma mark 返回每组尾部说明
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
    NSLog(@"生成尾部(组%i)详情",section);
    KCContactGroup *group=_contacts[section];
    return group.detail;
}
@end

运行可以看到如下效果:

Contact

大家在使用iPhone通讯录时会发现右侧可以按字母检索,使用起来很方便,其实这个功能使用UITableView实现很简单,只要实现数据源协议的一个方法,构建一个分组标题的数组即可实现。数组元素的内容和组标题内容未必完全一致,UITableView是按照数组元素的索引和每组数据索引顺序来定位的而不是按内容查找。

#pragma mark 返回每组标题索引
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    NSLog(@"生成组索引");
    NSMutableArray *indexs=[[NSMutableArray alloc]init];
    for(KCContactGroup *group in _contacts){
        [indexs addObject:group.name];
    }
    return indexs;
}

效果如下:

UITableViewIndex

需要注意的是上面几个重点方法的执行顺序,请看下图:

image

值得指出的是生成单元格的方法并不是一次全部调用,而是只会生产当前显示在界面上的单元格,当用户滚动操作时再显示其他单元格。

到这里数据源这块就结束了,有兴趣的同学可以接着往下学习。






iOS UITableView数据源与代理方法的调用(一)

UITableView在iOS中是最长使用的控件了,但在对于其中具体的代理以及数据源的调用顺序相信好多人并不太清楚。刚好最近工作中遇到一个由于不熟悉其中的加载机制造成了一个很奇葩的BUG,于是顺便研究...
  • yuanchao__2106
  • yuanchao__2106
  • 2016年08月01日 17:01
  • 1278

UI -- UITableView 数据源协议与委托协议

与UIPickerView等复杂控件类似,表视图在开发过程中也会使用委托协议和数据源协议,而表视图UITableView的数据源协议是UITableViewDataSource,委托协议是UITabl...
  • honey199396
  • honey199396
  • 2016年07月13日 11:22
  • 553

学习笔记-UITableView的数据源(dataSource)和代理(delegate)

UITableView的数据源(dataSource)和代理(delegate)   UITableView需要一个数据源(dataSource)来显示数据,UITableView会向数据...
  • CrazyChickOne
  • CrazyChickOne
  • 2014年08月20日 12:43
  • 29205

UITableView刷新某一行,改变数据源的问题

对于从字典中取值给cell赋值的,可以创建一个可变字典,每次从这个可变字典中取值赋值给cell,需要改变时,将这个可变字典中的值改变,然后再刷新即可。例如: [WebConnect webPOSTCo...
  • ideaspress
  • ideaspress
  • 2015年12月21日 16:23
  • 1502

Swift4.0 学习笔记 第十节:UITableView

////  ViewController.swift//  013-tableView////  Created by 庄壮勇 on 2018/1/4.//  Copyright © 2018年 Pe...
  • mn704058053
  • mn704058053
  • 2018年01月15日 10:25
  • 20

iOS Controller 瘦身运动之 UItableView datasource 与 delegate的分离

iOS Controller 瘦身运动之 UItableView datasource 与 delegate的分离         最近在公司进行了代码的一些优化,所以在空闲之余,把相关的经验...
  • zhonggaorong
  • zhonggaorong
  • 2016年03月15日 16:38
  • 1870

swift之UITableView的使用

原文地址:http://www.wugaojun.com/blog/2015/05/09/ru-he-da-jian-bo-ke/ 1.创建tableView Swift和OC中UITab...
  • HK_5788
  • HK_5788
  • 2016年04月05日 22:36
  • 1223

iOS UITableView的基本使用

【UITableView控件简单介绍】 一、数据展示 UITableView需要一个数据源(dataSource)来显示数据; UITableView会向数据源查询一共有多少行数据以及每行显示什么数据...
  • github_26672553
  • github_26672553
  • 2015年08月08日 10:02
  • 360

UI---UITableView

UITableView 在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView,UITableView继承自UIScrollView,因此支持垂直滚动,⽽且性能极佳 。UITab...
  • xiaomu_Sam1101
  • xiaomu_Sam1101
  • 2014年12月23日 22:09
  • 91

iphone开发之表格组件UITableView的使用(二)如何分组展示数据并添加组头和组尾描述

1、在实现UITAbleView数据源协议即UITableViewDataSource内的如下方法中: //  此方法用于告诉哪个UITableView的每一组的每一行显示什么内容 -(UITab...
  • u013087513
  • u013087513
  • 2015年08月30日 12:01
  • 896
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UItableView系列——数据源
举报原因:
原因补充:

(最多只允许输入30个字)