UI学习笔记---第十一天UITableView表视图高级-自定义cell
自定义cell,多类型cell混合使用,cell自适应高度
自定义cell就是创建一个UITableViewCell的子类
把cell上的空间创建都封装在子类中,简化viewController中的代码
cell中的空间如何显示Model中的信息
cell中声明一个Model类型的属性,viewController中获取到Model对象后赋值给cell的Model属性
cell中重写Model的setter方法,把Model对象中的内容重新赋值给各个控件
M和V不直接通信,C负责M和V之间进行通信
多类型cell混合使用
通常我们会在tableView:cellForRowAtIndexPath:方法中根据不同的Model来决定使用什么类型的cell
每种类型的cell要定义不同的重用标识符
cell重用的时候会根据重用标识从重用队列中取用那种类型的cell
cell自适应高度
实际开发中经常要让cell根据Model中文本的长短动态的更改高度
获取文本高度 ---计算一段文本在限定宽高内所占矩形大小
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary*)attributes context:(NSStringDrawingContext *)context
计算文本高度是所用字体要和label显示时所用的字体一致
label的宽度要和计算时所用的限定宽度一致这样才能保证文本显示在label中时,label的高度恰巧够
cell自适应高度
tableView:heightForRowAtIndexPath:⽅法要比
tableView:cellForRowAtIndexPath先执行。
所以要提前计算好每行cell需要多少高度
练习代码
AppDalegate.m中创建根表视图控制器,导航控制器
RootTableViewController *rootVC = [[RootTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *ngVc = [[UINavigationController alloc] initWithRootViewController:rootVC];
self.window.rootViewController = ngVc;
[ngVc release];
[rootVC release];
RootTableViewController控制器类中代码
//.h中代码
#import <UIKit/UIKit.h> @interface RootTableViewController : UITableViewController {
NSMutableArray *_studentsArray;
}
@end
//.m中代码
#import "RootTableViewController.h"
#import "StudentCell.h"
#import "Student.h"
#import "SecondCell.h"
@interface RootTableViewController () @end @implementation RootTableViewController - (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
self.navigationItem.title =@"通讯录";
// Custom initialization
}
return self;
} - (void)viewDidLoad
{
[super viewDidLoad]; //这是一个单例,用来取文件路径
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Students" ofType:@"plist"]; NSArray *students = [[NSArray alloc] initWithContentsOfFile:filePath]; _studentsArray = [[NSMutableArray alloc] initWithCapacity:[students count]];
for (int i = ; i<[students count]; i++) {
NSDictionary *dic = [students objectAtIndex:i];
Student *stu = [[Student alloc] init];
//使用kvc
[stu setValuesForKeysWithDictionary:dic];
[_studentsArray addObject:stu];
[stu release];
}
[students release];
NSLog(@"%@",_studentsArray);
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO; // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
} - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return ;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [_studentsArray count];
} /////********************一种方法************************
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//{
// static NSString *identifier = @"cell";
//
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
// if (cell == nil) {
// cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
// }
// //创建一个label
// [[cell.contentView viewWithTag:1000] removeFromSuperview];
// UILabel *sexlabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 0, 100, 40)];
// sexlabel.tag = 1000;
// [cell.contentView addSubview:sexlabel];
// [sexlabel release];
//
//
// NSDictionary *student = [_studentsArray objectAtIndex:indexPath.row];
//
// cell.textLabel.text = [student objectForKey:@"name"];
// sexlabel.text = [student objectForKey:@"sex"];
//
// // Configure the cell...
//
// return cell;
//}
//
////********************方法二*********************
//- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//{
// static NSString *identifier = @"cell";
//
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
// if (cell == nil) {
// cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
// //创建一个cell创建一个label,第一种方法的优化,第一种方法一直开辟空间释放空间,占用系统资源
// [[cell.contentView viewWithTag:1000] removeFromSuperview];
// UILabel *sexlabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 0, 100, 40)];
// sexlabel.tag = 1000;
// [cell.contentView addSubview:sexlabel];
// [sexlabel release];
// }
// //if中的sexlabel是一个局部变量,需要在外面重写一个label接受tag=1000的label
// UILabel *sexlabel = (UILabel *)[cell.contentView viewWithTag:1000];
//
// NSDictionary *student = [_studentsArray objectAtIndex:indexPath.row];
//
// cell.textLabel.text = [student objectForKey:@"name"];
// sexlabel.text = [student objectForKey:@"sex"];
//
//
// // Configure the cell...
//
// return cell;
//}
/////***************第三种建一个UITableViewCell子类*******************
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Student *stu = [_studentsArray objectAtIndex:indexPath.row];
if ([stu.sex isEqualToString:@"男"]) {
static NSString *identifier = @"cell1";
StudentCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[StudentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
}
cell.stu = _studentsArray[indexPath.row];
return cell;
}else{
static NSString *identifier = @"cell"; SecondCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[SecondCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease]; } cell.stu = _studentsArray[indexPath.row]; // Configure the cell... return cell; } // static NSString *identifier = @"cell";
//
// SecondCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
// if (cell == nil) {
// cell = [[[SecondCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
//
// }
//
//
//// Student *student = [_studentsArray objectAtIndex:indexPath.row];
//// [cell setStu:student];
// cell.stu = _studentsArray[indexPath.row];
//// cell.nameLabel.text = student.name;
//// cell.sexLabel.text = student.sex;
//// cell.phoneLabel.text = student.phone;
//// cell.photoImageView.image = [UIImage imageNamed:student.photo];
//
//
//
//
// // Configure the cell...
//
// return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// CGFloat height = Studentcell;
Student *stu = [_studentsArray objectAtIndex:indexPath.row];
CGRect rect = [stu.hobby boundingRectWithSize:CGSizeMake(, ) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:],NSFontAttributeName, nil] context:nil];
if ([stu.sex isEqualToString:@"男"]) { return +rect.size.height+;
}else{ return +rect.size.height+;
} }
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/ /*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/ /*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/ /*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/ /*
#pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/ @end
自定义cell----StudentCell中代码
//.h中代码
#import <UIKit/UIKit.h>
#import "Student.h"
@interface StudentCell : UITableViewCell
@property (nonatomic,retain) UILabel *nameLabel;
@property (nonatomic,retain) UILabel *sexLabel;
@property (nonatomic,retain) UILabel *phoneLabel;
@property (nonatomic,retain) UIImageView *photoImageView;
@property (nonatomic,retain) UILabel *hobbyLabel;
//对cell中需要显示的数据进行封装,创建一个Student Model类
@property (nonatomic,retain) Student *stu; @end
//.m中代码
#import "StudentCell.h" @implementation StudentCell
-(void)dealloc
{
[_photoImageView release];
[_nameLabel release];
[_sexLabel release];
[_phoneLabel release];
[super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//自定义cell
self.photoImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.nameLabel = [[[UILabel alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.sexLabel = [[[UILabel alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.phoneLabel = [[[UILabel alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.hobbyLabel = [[[UILabel alloc] initWithFrame:CGRectMake(, , , )] autorelease];
//给hobbylabel设定一个字号,在表视图控制器里面直接可以使用
self.hobbyLabel.font = [UIFont systemFontOfSize:];
//让它自适应高度,把行数设为0
self.hobbyLabel.numberOfLines = ; [self.contentView addSubview:_photoImageView];
[self.contentView addSubview:_nameLabel];
[self.contentView addSubview:_sexLabel];
[self.contentView addSubview:_phoneLabel];
[self.contentView addSubview:_hobbyLabel]; // Initialization code
}
return self;
} - (void)awakeFromNib
{
// Initialization code
} - (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated]; // Configure the view for the selected state
}
//重写setter方法
- (void)setStu:(Student *)stu
{
self.nameLabel.text = stu.name;
self.sexLabel.text = stu.sex;
self.phoneLabel.text = stu.phone; self.photoImageView.image = [UIImage imageNamed:stu.photo];
//设置爱好自定义高度
CGRect rect = [stu.hobby boundingRectWithSize:CGSizeMake(, ) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:self.hobbyLabel.font,NSFontAttributeName, nil] context:nil];
self.hobbyLabel.frame = CGRectMake(, , , rect.size.height);
self.hobbyLabel.text = stu.hobby; } @end
自定义另一个cell----SecondCell
//.h中代码
#import <UIKit/UIKit.h>
#import "Student.h"
@interface SecondCell : UITableViewCell
@property (nonatomic,retain) UILabel *nameLabel;
@property (nonatomic,retain) UILabel *sexLabel;
@property (nonatomic,retain) UILabel *phoneLabel;
@property (nonatomic,retain) UIImageView *photoImageView;
@property (nonatomic,retain) UILabel *hobbyLabel; @property (nonatomic,retain) Student *stu;
@end
//.m中代码
#import "SecondCell.h" @implementation SecondCell
-(void)dealloc
{
[_photoImageView release];
[_nameLabel release];
[_sexLabel release];
[_phoneLabel release];
[_hobbyLabel release];
[super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//自定义cell
self.photoImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.nameLabel = [[[UILabel alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.sexLabel = [[[UILabel alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.phoneLabel = [[[UILabel alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.hobbyLabel = [[[UILabel alloc] initWithFrame:CGRectMake(, , , )] autorelease];
self.hobbyLabel.font = [UIFont systemFontOfSize:]; [self.contentView addSubview:_photoImageView];
[self.contentView addSubview:_nameLabel];
[self.contentView addSubview:_sexLabel];
[self.contentView addSubview:_phoneLabel];
[self.contentView addSubview:_hobbyLabel];
// Initialization code
}
return self;
} - (void)awakeFromNib
{
// Initialization code
} - (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated]; // Configure the view for the selected state
}
//重写setter方法
- (void)setStu:(Student *)stu
{
self.nameLabel.text = stu.name;
self.sexLabel.text = stu.sex;
self.phoneLabel.text = stu.phone;
self.photoImageView.image = [UIImage imageNamed:stu.photo];
CGRect rect = [stu.hobby boundingRectWithSize:CGSizeMake(, ) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:],NSFontAttributeName, nil] context:nil]; self.hobbyLabel.frame = CGRectMake(, , , rect.size.height);
self.hobbyLabel.text = stu.hobby; } @end
Model类-----Student
//.h中代码
#import <Foundation/Foundation.h> @interface Student : NSObject
@property (nonatomic,retain) NSString *name;
@property (nonatomic,retain) NSString *sex;
@property (nonatomic,retain) NSString *phone;
@property (nonatomic,retain) NSString *photo;
@property (nonatomic,retain) NSString *hobby; //- (instancetype)initWithName:(NSString *)name sex:(NSString *)sex phone:(NSString *)phone photo:(NSString *)photo hobby:(NSString *)hobby;
//
//- (instancetype)initWithDictionary:(NSDictionary *)stuInfoDic;
@end
//.m中代码
#import "Student.h" @implementation Student
-(void)dealloc
{
[_name release];
[_sex release];
[_phone release];
[_photo release];
[_hobby release];
[super dealloc];
}
//用KVC取值,不用初始化方法
//- (instancetype)initWithName:(NSString *)name sex:(NSString *)sex phone:(NSString *)phone photo:(NSString *)photo hobby:(NSString *)hobby
//{
// self = [super init];
// if (self) {
// self.name = name;
// self.sex = sex;
// self.phone = phone;
// self.photo = photo;
// self.hobby = hobby;
// }
// return self;
//}
//
//- (instancetype)initWithDictionary:(NSDictionary *)stuInfoDic
//{
// self = [super init];
// if (self) {
// self.name = [stuInfoDic objectForKey:@"name"];
// self.sex = [stuInfoDic objectForKey:@"sex"];
// self.phone = [stuInfoDic objectForKey:@"phone"];
// self.photo = [stuInfoDic objectForKey:@"photo"];
// self.hobby = [stuInfoDic objectForKey:@"hobby"];
// }
// return self;
//} -(void)setValue:(id)value forUndefinedKey:(NSString *)key
{ }
@end
数据来源是创建一个plist文件


查看plist源代码

UI学习笔记---第十一天UITableView表视图高级-自定义cell的更多相关文章
- UI学习笔记---第十天UITableView表视图编辑
UITableView表视图编辑 表视图编辑的使用场景 当我们需要手动添加或者删除某条数据到tableView中的时候,就可以使用tableView编辑.比如微信 扣扣中删除和某人的通话 当我们需要手 ...
- UI学习笔记---第九天UITableView表视图
UITableView表视图 一.表视图的使用场景 表视图UITableView是iOS中最重要的视图,随处可见,通常用来管理一组具有相同数据结构的数据 表视图继承自UIScrollView,所以可以 ...
- VSTO 学习笔记(十一)开发Excel 2010 64位自定义公式
原文:VSTO 学习笔记(十一)开发Excel 2010 64位自定义公式 Excel包含很多公式,如数学.日期.文本.逻辑等公式,非常方便,可以灵活快捷的对数据进行处理,达到我们想要的效果.Exce ...
- Python学习笔记(十一)
Python学习笔记(十一): 生成器,迭代器回顾 模块 作业-计算器 1. 生成器,迭代器回顾 1. 列表生成式:[x for x in range(10)] 2. 生成器 (generator o ...
- angular学习笔记(三十一)-$location(2)
之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍 ...
- angular学习笔记(三十一)-$location(1)
本篇介绍angular中的$location服务的基本用法,下一篇介绍它的复杂的用法. $location服务的主要作用是用于获取当前url以及改变当前的url,并且存入历史记录. 一. 获取url的 ...
- python3.4学习笔记(二十一) python实现指定字符串补全空格、前面填充0的方法
python3.4学习笔记(二十一) python实现指定字符串补全空格.前面填充0的方法 Python zfill()方法返回指定长度的字符串,原字符串右对齐,前面填充0.zfill()方法语法:s ...
- EF学习笔记(十二):EF高级应用场景
学习总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 上篇链接:EF学习笔记(十一):实施继承 本篇原文链接:Advanced Entity Framework Scenari ...
- UITableView表视图以及重建机制
表视图UITableView 表视图UITableView,是IOS中最重要的视图,随处可见 表视图通常用来管理一组具有相同数据结构的数据 UITableView继承自UIScrollView,所 ...
随机推荐
- java反射之Class.getMethod与getDeclaredMethods()区别
Class对象的getMethods和getDeclaredMethods都是获取类对象的方法.但是又有所不同.废话不多说, 先看demo package com.westward; public c ...
- Linux下的多线程编程
1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(proces ...
- 4通用Makefile编写
a.c #include<stdio.h> #include "a.h" int main() { printf("hello world\n"); ...
- localStorage
length:唯一的属性,只读,用来获取storage内的键值对数量. key:根据index获取storage的键名 getItem:根据key获取storage内的对应value setItem: ...
- MongoDB Aggregate Methods(2) MonoDB 的 3 种聚合函数
aggregate(pipeline,options) 指定 group 的 keys, 通过操作符 $push/$addToSet/$sum 等实现简单的 reduce, 不支持函数/自定义变量 g ...
- 图书馆管理系统SRS
1.任务概述 1.1目标 主要提供图书信息和读者基本信息的维护以及借阅等功能.本系统是提高图书管理工作的效率,减少相关人员的工作量,使学校的图书管理工作真正做到科学.合理的规划,系统.高效的实施. 1 ...
- S5PV210之添加缺少的-内核提供的'.h'文件 linux3.0.8驱动
怎样解决编译时出现内核提供的函数或变量没有定义,使用source insight搜索功能找到声明的头文件,然后包含该头件就行了: 比如: error: implicit declaration of ...
- xcode开发的6个小技巧
Xcode是iPhone和iPad开发者用来编码或者开发iOS app的IDE.Xcode有很多小巧但很有用的功能,很多时候我们可能没有注意到它们,也或者我们没有在合适的水平使用这些功能简化我们的iO ...
- iOS 网络判定
由于流量精灵需要在 蜂窝数据或者3G 环境下进行流量监控因此需要判定3G 环境 将 SystemConfiguration.framework 添加进工程: 引入头文件 #import <Sys ...
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...