UI基础 - UITableView 03:给单元格绑定数据
■ 数据绑定
1. 准备工作
学生信息文件 Students.plist
数据源 Student:用来存储学生信息
Model层 StudentData 文件:管理数据
自定制两种 cell 布局:按照性别不同,决定 cell 的布局样式
2. 具体实现
// - Student.h:Student.m 中无实质性内容,已忽略
1 #import <Foundation/Foundation.h> 2 @interface Student : NSObject 3 4 @property(nonatomic,copy)NSString *name; // 姓名 5 @property(nonatomic,copy)NSString *sex; // 性别 6 @property(nonatomic,copy)NSString *phoneNumber; // 电话 7 @property(nonatomic,copy)NSString *icon; // 头像 8 @property(nonatomic,copy)NSString *introduce;// 简介 9 10 @end
// - StudentData.h
1 #import <Foundation/Foundation.h> 2 @class Student; 3 @interface StudentData : NSObject 4 5 @property(nonatomic,strong)NSMutableArray *dataArray; 6 7 + (StudentData *)shareDataHandle; 8 - (Student *)studentIndexPath:(NSIndexPath *)indexPath;// 根据下标返回学生对象 9 10 @end
// - StudentData.m
1 #import "StudentData.h" 2 #import "Student.h" 3 #import <UIKit/UIKit.h> 4 static StudentData *stuData = nil; 5 @implementation StudentData 6 7 + (StudentData *)shareDataHandle{ 8 9 if (stuData == nil) { 10 stuData = [[StudentData alloc] init]; 11 [stuData loadDataFromPlist]; 12 } 13 14 return stuData; 15 } 16 17 // 获取本地数据 18 - (void)loadDataFromPlist{ 19 20 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Students" ofType:@"plist"]; 21 NSArray *plistArray = [NSArray arrayWithContentsOfFile:filePath]; 22 23 // 存入数据源 24 self.dataArray = [NSMutableArray arrayWithCapacity:1]; 25 for (NSDictionary *dic in plistArray) { 26 Student *student = [[Student alloc] init]; 27 student.name = [dic objectForKey:@"name"]; 28 student.sex = [dic objectForKey:@"sex"]; 29 student.phoneNumber = [dic objectForKey:@"phoneNumber"]; 30 student.introduce = [dic objectForKey:@"introduce"]; 31 student.icon = [dic objectForKey:@"icon"]; 32 [_dataArray addObject:student]; 33 } 34 } 35 36 // 根据下标,返回学生对象 37 - (Student *)studentIndexPath:(NSIndexPath *)indexPath{ 38 39 return _dataArray[indexPath.row]; 40 } 41 42 @end
// - BoyCell.h
1 #import <UIKit/UIKit.h> 2 @class Student; 3 @interface BoyCell : UITableViewCell 4 5 @property(nonatomic,strong)UIImageView *iconImageView; 6 @property(nonatomic,strong)UILabel *nameLabel; 7 @property(nonatomic,strong)UILabel *sexLabel; 8 @property(nonatomic,strong)UILabel *phoneNumberLabel; 9 @property(nonatomic,strong)UILabel *introduceLabel; 10 11 // 自适应高度 12 + (CGFloat )cellHeight:(Student *)stu; 13 14 // 赋值 15 // 方式一:提供一个新的接口并实现赋值 16 //-(void)displayData:(Student *)stu; 17 18 // 方式二:使用属性 19 @property(nonatomic,strong)Student *stu; 20 21 @end
// - BoyCell.m
1 #import "BoyCell.h" 2 #import "Student.h" 3 #define K_LEFT_MARGIN 10 4 #define K_TOP_MARGIN 10 5 #define K_IOCN_SIZE 80 6 #define K_LABLE_HEIGHT 35 7 #define K_SPACE 10 8 #define W_TEXT [UIScreen mainScreen].bounds.size.width - 2*K_LEFT_MARGIN 9 @implementation BoyCell 10 - (void)awakeFromNib { 11 [super awakeFromNib]; 12 } 13 14 - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 15 [super setSelected:selected animated:animated]; 16 } 17 18 19 20 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 21 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 22 if (self) { 23 24 // 头像 25 self.iconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(K_LEFT_MARGIN, K_TOP_MARGIN, K_IOCN_SIZE, K_IOCN_SIZE)]; 26 //_iconImageView.backgroundColor = [UIColor orangeColor]; 27 self.iconImageView.layer.cornerRadius = K_IOCN_SIZE/2.0; 28 self.iconImageView.clipsToBounds = YES; 29 [self.contentView addSubview:_iconImageView]; 30 31 // 姓名 32 self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_iconImageView.frame) + K_SPACE, CGRectGetMinY(_iconImageView.frame), 100, K_LABLE_HEIGHT)]; 33 //_nameLabel.backgroundColor = [UIColor orangeColor]; 34 [self.contentView addSubview:_nameLabel]; 35 36 // 性别 37 self.sexLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_nameLabel.frame)+K_SPACE, CGRectGetMinY(_nameLabel.frame), 100, K_LABLE_HEIGHT)]; 38 //_sexLabel.backgroundColor = [UIColor orangeColor]; 39 [self.contentView addSubview:_sexLabel]; 40 41 // 电话号码 42 self.phoneNumberLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(_nameLabel.frame), CGRectGetMaxY(_nameLabel.frame)+K_SPACE, 210, K_LABLE_HEIGHT)]; 43 //_phoneNumberLabel.backgroundColor = [UIColor orangeColor]; 44 [self.contentView addSubview:_phoneNumberLabel]; 45 46 // 简介 47 self.introduceLabel = [[UILabel alloc] initWithFrame:CGRectMake(K_LEFT_MARGIN, CGRectGetMaxY(_iconImageView.frame)+ K_SPACE, W_TEXT, 30)]; 48 //_introduceLabel.backgroundColor = [UIColor orangeColor]; 49 _introduceLabel.numberOfLines = 0; 50 [self.contentView addSubview:_introduceLabel]; 51 } 52 53 return self; 54 } 55 56 //// 方式一 57 //-(void)displayData:(Student *)stu{ 58 // 59 // self.iconImageView.image = [UIImage imageNamed:stu.icon]; 60 // self.nameLabel.text = stu.name; 61 // self.sexLabel.text = stu.sex; 62 // self.phoneNumberLabel.text = stu.phoneNumber; 63 // self.introduceLabel.text = stu.introduce; 64 //} 65 66 // 方式二 67 -(void)setStu:(Student *)stu{ 68 if (stu != _stu) { 69 _stu = stu ; 70 } 71 72 _iconImageView.image = [UIImage imageNamed:stu.icon]; 73 _nameLabel.text = stu.name; 74 _sexLabel.text = stu.sex; 75 _phoneNumberLabel.text = [NSString stringWithFormat:@"战斗指数:%@",stu.phoneNumber]; 76 77 // cell自适应高度 78 NSDictionary *textDic = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:17],NSFontAttributeName, nil]; 79 CGRect rect = [stu.introduce boundingRectWithSize:CGSizeMake(W_TEXT, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:textDic context:nil]; 80 81 _introduceLabel.frame = CGRectMake(_introduceLabel.frame.origin.x, _introduceLabel.frame.origin.y, _introduceLabel.frame.size.width, rect.size.height); 82 _introduceLabel.text = stu.introduce; 83 } 84 85 + (CGFloat)cellHeight:(Student *)stu{ 86 87 NSDictionary *textDic = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:17],NSFontAttributeName, nil]; 88 CGRect rect = [stu.introduce boundingRectWithSize:CGSizeMake(W_TEXT, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:textDic context:nil]; 89 return K_TOP_MARGIN * 2 + K_IOCN_SIZE + K_SPACE + rect.size.height; 90 } 91 @end
// - GirlCell.h
1 #import <UIKit/UIKit.h> 2 @class Student; 3 @interface GirlCell : UITableViewCell 4 5 @property(nonatomic,strong)UIImageView *iconImageView; 6 @property(nonatomic,strong)UILabel *nameLabel; 7 @property(nonatomic,strong)UILabel *sexLabel; 8 @property(nonatomic,strong)UILabel *phoneNumberLabel; 9 @property(nonatomic,strong)UILabel *introduceLabel; 10 11 @property(nonatomic,strong)Student *stu; 12 + (CGFloat )cellHeight:(Student *)stu; 13 14 @end
// - GirlCell.m
1 #import "GirlCell.h" 2 #import "Student.h" 3 #define K_LEFT_MARGIN 10 4 #define K_TOP_MARGIN 10 5 #define K_IOCN_SIZE 80 6 #define K_LABLE_HEIGHT 35 7 #define K_SPACE 10 8 // 简介宽度 9 #define W_TEXT [UIScreen mainScreen].bounds.size.width - 2*K_LEFT_MARGIN 10 @implementation GirlCell 11 12 - (void)awakeFromNib { 13 [super awakeFromNib]; 14 } 15 16 - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 17 [super setSelected:selected animated:animated]; 18 19 // Configure the view for the selected state 20 } 21 22 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 23 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 24 if (self) { 25 26 self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(K_LEFT_MARGIN, K_TOP_MARGIN, 100, K_LABLE_HEIGHT)]; 27 //_nameLabel.backgroundColor = [UIColor purpleColor]; 28 [self.contentView addSubview:_nameLabel]; 29 30 self.sexLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_nameLabel.frame)+K_SPACE, CGRectGetMinY(_nameLabel.frame), 100, K_LABLE_HEIGHT)]; 31 //_sexLabel.backgroundColor = [UIColor purpleColor]; 32 [self.contentView addSubview:_sexLabel]; 33 34 self.phoneNumberLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(_nameLabel.frame), CGRectGetMaxY(_nameLabel.frame)+K_SPACE, 210, K_LABLE_HEIGHT)]; 35 //_phoneNumberLabel.backgroundColor = [UIColor purpleColor]; 36 [self.contentView addSubview:_phoneNumberLabel]; 37 38 self.iconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_phoneNumberLabel.frame) + K_SPACE, K_TOP_MARGIN, K_IOCN_SIZE, K_IOCN_SIZE)]; 39 //_iconImageView.backgroundColor = [UIColor purpleColor]; 40 self.iconImageView.clipsToBounds = YES; 41 self.iconImageView.layer.cornerRadius = K_IOCN_SIZE/2.0; 42 [self.contentView addSubview:_iconImageView]; 43 44 self.introduceLabel = [[UILabel alloc] initWithFrame:CGRectMake(K_LEFT_MARGIN, CGRectGetMaxY(_iconImageView.frame)+ K_SPACE, W_TEXT, 30)]; 45 //_introduceLabel.backgroundColor = [UIColor purpleColor]; 46 _introduceLabel.numberOfLines = 0; 47 [self.contentView addSubview:_introduceLabel]; 48 49 } 50 51 return self; 52 } 53 54 - (void)setStu:(Student *)stu{ 55 56 if (stu != _stu) { 57 _stu = stu; 58 } 59 60 _iconImageView.image = [UIImage imageNamed:stu.icon]; 61 _nameLabel.text = stu.name; 62 _sexLabel.text = stu.sex; 63 _phoneNumberLabel.text = [NSString stringWithFormat:@"战斗指数:%@",stu.phoneNumber]; 64 65 NSDictionary * textDic = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:17],NSFontAttributeName, nil]; 66 CGRect rect = [stu.introduce boundingRectWithSize:CGSizeMake(W_TEXT, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:textDic context:nil]; 67 _introduceLabel.frame = CGRectMake(_introduceLabel.frame.origin.x, _introduceLabel.frame.origin.y, _introduceLabel.frame.size.width, rect.size.height); 68 _introduceLabel.text = stu.introduce; 69 } 70 71 + (CGFloat )cellHeight:(Student *)stu{ 72 73 NSDictionary * textDic = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:17],NSFontAttributeName, nil]; 74 CGRect rect = [stu.introduce boundingRectWithSize:CGSizeMake(W_TEXT, 0) options:NSStringDrawingUsesLineFragmentOrigin attributes:textDic context:nil]; 75 return K_TOP_MARGIN * 2 + K_IOCN_SIZE + K_SPACE + rect.size.height; 76 } 77 78 @end
// - ViewController.m
1 #import "ViewController.h" 2 #import "Student.h" 3 #import "StudentData.h" 4 #import "GirlCell.h" 5 #import "BoyCell.h" 6 @interface ViewController()<UITableViewDataSource,UITableViewDelegate> 7 8 @property(nonatomic,strong)UITableView *tableView; 9 10 @end 11 12 @implementation ViewController 13 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 self.view.backgroundColor = [UIColor redColor]; 17 self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.height-64) style:UITableViewStylePlain]; 18 self.tableView.backgroundColor = [UIColor cyanColor]; 19 self.tableView.delegate = self; 20 self.tableView.dataSource = self; 21 [self.view addSubview:self.tableView]; 22 23 } 24 25 #pragma mark - <UITableViewDataSource> 26 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 27 28 return 1; 29 } 30 31 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 32 33 return [StudentData shareDataHandle].dataArray.count; 34 } 35 36 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 37 38 // 获取学生对象 39 Student *stu = [[StudentData shareDataHandle] studentIndexPath:indexPath]; 40 41 // 根据数据源,初始化 cell 42 if ([stu.sex isEqualToString:@"男"]) { 43 44 static NSString *boyCellIndentifier = @"boyCell"; 45 BoyCell *boyCell = [tableView dequeueReusableCellWithIdentifier:boyCellIndentifier]; 46 if (!boyCell) { 47 boyCell = [[BoyCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:boyCellIndentifier]; 48 } 49 50 boyCell.stu = stu;// 属性赋值 51 return boyCell; 52 } 53 54 static NSString *girlCellIndentifier = @"girlCell"; 55 GirlCell *girlCell = [tableView dequeueReusableCellWithIdentifier:girlCellIndentifier]; 56 if (!girlCell) { 57 girlCell = [[GirlCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:girlCellIndentifier]; 58 } 59 60 girlCell.stu = stu; 61 return girlCell; 62 } 63 64 #pragma mark - <UITableViewDelegate> 65 // 自适应高度 66 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 67 Student *stu = [[StudentData shareDataHandle] studentIndexPath:indexPath]; 68 if ([stu.sex isEqualToString:@"男"]) { 69 return [BoyCell cellHeight:stu]; 70 } 71 return [GirlCell cellHeight:stu]; 72 } 73 74 @end
运行效果
分类:
UI章节
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律