iOS编程中的UITableView详解(数据源dataSource)

一、UITableView基本介绍

iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,微信、QQ、新浪微博等软件基本都有UITableView。
UITableView有两种style:
UITableViewStylePlain


232318440491185.png

UITableViewStyleGrouped。


image.png

UITableView中数据只有行的概念,并没有列的概念,因为在手机操作系统中显示多列是不利于操作的。UITableView中每行数据都是一个UITableViewCell,在这个控件中为了显示更多的信息,iOS已经在其内部设置好了多个子控件以供开发者使用。如果我们查看UITableViewCell的声明文件可以发现在内部有一个UIView控件(contentView,作为其他元素的父控件)、两个UILable控件(textLabel、detailTextLabel)、一个UIImage控件(imageView),分别用于容器、显示内容、详情和图片。不同的UItableViewCell不同的类型:

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
    UITableViewCellStyleDefault,    // 左侧显示textLabel(不显示detailTextLabel),imageView可选(显示在最左边)
    UITableViewCellStyleValue1,        // 左侧显示textLabel、右侧显示detailTextLabel(默认蓝色),imageView可选(显示在最左边)
    UITableViewCellStyleValue2,        // 左侧依次显示textLabel(默认蓝色)和detailTextLabel,imageView可选(显示在最左边)
    UITableViewCellStyleSubtitle    // 左上方显示textLabel,左下方显示detailTextLabel(默认灰色),imageView可选(显示在最左边)
};
数据源dataSource

UITableView设置完dataSource后需要实现UITableViewDataSource协议,在这个协议中定义了多种数据操作方法,创建一个简单的联系人管理进行演示:

#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface ContectUserInfo : NSObject
#pragma mark 姓
@property (nonatomic,copy) NSString *firstName;
#pragma mark 名
@property (nonatomic,copy) NSString *lastName;
#pragma mark 手机号码
@property (nonatomic,copy) NSString *phoneNumber;
#pragma mark 带参数的构造函数
-(ContectUserInfo *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber;
#pragma mark 取得姓名
-(NSString *)getName;
#pragma mark 带参数的静态对象初始化方法
+(ContectUserInfo *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber;
@end
NS_ASSUME_NONNULL_END
#import "ContectUserInfo.h"
@implementation ContectUserInfo
-(ContectUserInfo *)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];
}
+(ContectUserInfo *)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andPhoneNumber:(NSString *)phoneNumber{
    ContectUserInfo *contact1=[[ContectUserInfo alloc]initWithFirstName:firstName andLastName:lastName andPhoneNumber:phoneNumber];
    return contact1;
}
@end
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface ContectUserInfoGroup : NSObject
#pragma mark 组名
@property (nonatomic,copy) NSString *name;
#pragma mark 分组描述
@property (nonatomic,copy) NSString *detail;
#pragma mark 联系人
@property (nonatomic,strong) NSMutableArray *contacts;
#pragma mark 带参数个构造函数
-(ContectUserInfoGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts;
#pragma mark 静态初始化方法
+(ContectUserInfoGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts;
@end
NS_ASSUME_NONNULL_END

#import "ContectUserInfoGroup.h"
@implementation ContectUserInfoGroup
-(ContectUserInfoGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts{
    if (self=[super init]) {
        self.name=name;
        self.detail=detail;
        self.contacts=contacts;
    }
    return self;
}

+(ContectUserInfoGroup *)initWithName:(NSString *)name andDetail:(NSString *)detail andContacts:(NSMutableArray *)contacts{
    ContectUserInfoGroup *group1=[[ContectUserInfoGroup alloc]initWithName:name andDetail:detail andContacts:contacts];
    return group1;
}
@end
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ContactViewController : UIViewController
@end
NS_ASSUME_NONNULL_END
#import "ContactViewController.h"
#import "ContectUserInfo.h"
#import "ContectUserInfoGroup.h"
@interface ContactViewController ()<UITableViewDataSource>

@property (nonatomic, strong) UITableView *tableView;

@property (nonatomic, strong) NSMutableArray *contaceList;

@end

@implementation ContactViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"tableView分组数据源";
    [self.view addSubview:self.tableView];
    
    // Do any additional setup after loading the view.
}

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

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

#pragma mark返回每行的单元格
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    //NSIndexPath是一个结构体,记录了组和行信息
    NSLog(@"生成单元格(组:%li,行%li)",(long)indexPath.section,(long)indexPath.row);
    ContectUserInfoGroup *group=[self.contaceList objectAtIndex:indexPath.section];
    ContectUserInfo *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(@"生成组(组%li)名称",(long)section);
    ContectUserInfoGroup *group=[self.contaceList objectAtIndex:section];
    return group.name;
}

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

- (NSMutableArray *)contaceList{
    if (!_contaceList) {
        _contaceList = [NSMutableArray array];
        ContectUserInfo *contact1=[ContectUserInfo initWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"];
        ContectUserInfo *contact2=[ContectUserInfo initWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"];
        ContectUserInfoGroup *group1=[ContectUserInfoGroup initWithName:@"C" andDetail:@"With names beginning with C" andContacts:[NSMutableArray arrayWithObjects:contact1,contact2, nil]];
        [_contaceList addObject:group1];
        
        
        
        ContectUserInfo *contact3=[ContectUserInfo initWithFirstName:@"Lee" andLastName:@"Terry" andPhoneNumber:@"18500131238"];
        ContectUserInfo *contact4=[ContectUserInfo initWithFirstName:@"Lee" andLastName:@"Jack" andPhoneNumber:@"18500131239"];
        ContectUserInfo *contact5=[ContectUserInfo initWithFirstName:@"Lee" andLastName:@"Rose" andPhoneNumber:@"18500131240"];
        ContectUserInfoGroup *group2=[ContectUserInfoGroup initWithName:@"L" andDetail:@"With names beginning with L" andContacts:[NSMutableArray arrayWithObjects:contact3,contact4,contact5, nil]];
        [_contaceList addObject:group2];
        
        
        
        ContectUserInfo *contact6=[ContectUserInfo initWithFirstName:@"Sun" andLastName:@"Kaoru" andPhoneNumber:@"18500131235"];
        ContectUserInfo *contact7=[ContectUserInfo initWithFirstName:@"Sun" andLastName:@"Rosa" andPhoneNumber:@"18500131236"];
        
        ContectUserInfoGroup *group3=[ContectUserInfoGroup initWithName:@"S" andDetail:@"With names beginning with S" andContacts:[NSMutableArray arrayWithObjects:contact6,contact7, nil]];
        [_contaceList addObject:group3];
        
        
        ContectUserInfo *contact8=[ContectUserInfo initWithFirstName:@"Wang" andLastName:@"Stephone" andPhoneNumber:@"18500131241"];
        ContectUserInfo *contact9=[ContectUserInfo initWithFirstName:@"Wang" andLastName:@"Lucy" andPhoneNumber:@"18500131242"];
        ContectUserInfo *contact10=[ContectUserInfo initWithFirstName:@"Wang" andLastName:@"Lily" andPhoneNumber:@"18500131243"];
        ContectUserInfo *contact11=[ContectUserInfo initWithFirstName:@"Wang" andLastName:@"Emily" andPhoneNumber:@"18500131244"];
        ContectUserInfo *contact12=[ContectUserInfo initWithFirstName:@"Wang" andLastName:@"Andy" andPhoneNumber:@"18500131245"];
        ContectUserInfoGroup *group4=[ContectUserInfoGroup initWithName:@"W" andDetail:@"With names beginning with W" andContacts:[NSMutableArray arrayWithObjects:contact8,contact9,contact10,contact11,contact12, nil]];
        [_contaceList addObject:group4];
        
        
        ContectUserInfo *contact13=[ContectUserInfo initWithFirstName:@"Zhang" andLastName:@"Joy" andPhoneNumber:@"18500131246"];
        ContectUserInfo *contact14=[ContectUserInfo initWithFirstName:@"Zhang" andLastName:@"Vivan" andPhoneNumber:@"18500131247"];
        ContectUserInfo *contact15=[ContectUserInfo initWithFirstName:@"Zhang" andLastName:@"Joyse" andPhoneNumber:@"18500131248"];
        ContectUserInfoGroup *group5=[ContectUserInfoGroup initWithName:@"Z" andDetail:@"With names beginning with Z" andContacts:[NSMutableArray arrayWithObjects:contact13,contact14,contact15, nil]];
        [_contaceList addObject:group5];
    }
    return _contaceList;
}

- (UITableView *)tableView{
    if (!_tableView) {
        _tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
        _tableView.backgroundColor = [UIColor whiteColor];
        _tableView.dataSource=self;//设置数据源,注意必须实现对应的UITableViewDataSource协议
    }
    return _tableView;
}
@end

#pragma mark 返回每组标题索引
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    NSLog(@"生成组索引");
    NSMutableArray *indexs=[[NSMutableArray alloc]init];
    for(ContectUserInfo *group in self.contaceList){
        [indexs addObject:group.firstName];
    }
    return indexs;
}
计算分组数>>>计算每组的行数>>>生成分组索引>>>依次生成每组的单元格

代理方法

#pragma mark - 代理方法
#pragma mark 设置分组标题内容高度
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    if(section==0){
        return 50;
    }
    return 40;
}

#pragma mark 设置每行高度(每行高度可以不一样)
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 45;
}

#pragma mark 设置尾部说明内容高度
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
    return 40;
}
点击监听
#pragma mark 点击行
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    _selectedIndexPath=indexPath;
    ContectUserInfoGroup *group=[self.contaceList objectAtIndex:indexPath.section];
    ContectUserInfo *contact=group.contacts[indexPath.row];
    //创建弹出窗口
    UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"System Info" message:[contact getName] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
    alert.alertViewStyle=UIAlertViewStylePlainTextInput; //设置窗口内容样式
    UITextField *textField= [alert textFieldAtIndex:0]; //取得文本框
    textField.text=contact.phoneNumber; //设置文本框内容
    [alert show]; //显示窗口
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354