效果:
描述:表视图中生成多个不同的cell,cell的高度跟文字内容的多少有关
要求:需要自己在网上下载一个plis文件,然后修改两个标题
一 : 创建工程文件UIAutomaticCellHeightPractce-11
二 : 这里使用手动释放,所以需要修改工程文件Automatic Reference Counting 修改为NO
三 : 修改引用计数方式
四 : 释放适量变量,以及对父集进行释放,并让自动释放self.window(autorelease)
五 : 导入.plist文件(直接拖进工程文件)
六 : 工程文件
七 :代码区(采用MVC的设计模式)
模型-视图-控制器(Model-View-Controller,MVC)
AppDelegate.h
1 #import
2
3 @interface AppDelegate : UIResponder
4
5 @property (retain, nonatomic) UIWindow *window;6
7
8 @end
AppDelegate.m
1 #import "AppDelegate.h"
2 #import "RootTableViewController.h"
3
4 @interfaceAppDelegate ()5
6 @end
7
8 @implementationAppDelegate9
10 - (void)dealloc11 {12 self.window =nil;13
14 [super dealloc];15 }16
17 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {18 self.window =[[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];19 //Override point for customization after application launch.
20 RootTableViewController *rootVC =[[RootTableViewController alloc] init];21
22 UINavigationController *navigationController =[[UINavigationController alloc] initWithRootViewController:rootVC];23
24 self.window.rootViewController =navigationController;25
26 [rootVC release];27
28 [navigationController release];29
30
31 self.window.backgroundColor =[UIColor whiteColor];32 [self.window makeKeyAndVisible];33 returnYES;34 }35
36 @end
RootTableViewController.h
1 #import
2
3 @interfaceRootTableViewController : UITableViewController4
5 @end
RootTableViewController.m
1 #import "RootTableViewController.h"
2 #import "CellViewModel.h"
3 #import "CellTableViewCell.h"
4 #define kCellTabelViewCell @"cell"
5
6 @interfaceRootTableViewController ()7
8 //创建公用数组
9 @property (nonatomic , retain) NSMutableArray *dataSourceArr;10
11 @end
12
13 @implementationRootTableViewController14
15 - (void)dealloc16 {17 self.dataSourceArr =nil;18
19 [super dealloc];20 }21
22 - (void)viewDidLoad {23 [super viewDidLoad];24
25 [self readDataFromNewsData];26
27 //注册CellTableView
28 [self.tableView registerClass:[CellTableViewCell class] forCellReuseIdentifier:kCellTabelViewCell];29
30 //Uncomment the following line to preserve selection between presentations.31 //self.clearsSelectionOnViewWillAppear = NO;32
33 //Uncomment the following line to display an Edit button in the navigation bar for this view controller.34 //self.navigationItem.rightBarButtonItem = self.editButtonItem;
35 }36
37 #pragma mark - 给dataSourceArr添加懒加载方法
38 -(NSMutableArray *)dataSourceArr {39
40 if (!_dataSourceArr) {41
42 self.dataSourceArr = [NSMutableArray arrayWithCapacity:0];43 }44
45 return[[_dataSourceArr retain] autorelease];46 }47
48
49 #pragma mark - 读取数据
50 -(void)readDataFromNewsData {51
52 //NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:0];53
54 //创建文件路径
55 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"NewsData.plist"ofType:nil];56
57 //根据路径将文件中的内容取出来存储到字典中
58 NSMutableDictionary *dic =[NSMutableDictionary dictionaryWithContentsOfFile:filePath];59
60 //根据key值取出对应的value值,这里假设要查找的文件内容为title,summary
61 NSArray *arr = dic[@"news"];62
63 //NSLog(@"%@" , arr);
64
65 for (NSDictionary *d inarr) {66
67 //创建一个CellViewModel对象存储数据
68 CellViewModel *dataBase =[[CellViewModel alloc] init];69
70 //使用kvc的方法给CellViewModel对象赋值
71
72 /*
73 2)代码说明:74
75 KVC key valued coding 键值编码76
77 1)使用KVC间接修改对象属性时,系统会自动判断对象属性的类型,并完成转换。如该程序中的“23”.78
79 2)KVC按照键值路径取值时,如果对象不包含指定的键值,会自动进入对象内部,查找对象属性80 */
81
82 [dataBase setValuesForKeysWithDictionary:d];83
84 //NSLog(@"%@" , dataBase);85
86 //将存储到CellViewModel对象的数据放入数组
87 [self.dataSourceArr addObject:dataBase];88
89 //NSLog(@"%@" , _dataSourceArr);90
91 //释放
92 [dataBase release];93 }94 }95
96
97 - (void)didReceiveMemoryWarning {98 [super didReceiveMemoryWarning];99 //Dispose of any resources that can be recreated.
100 }101
102 #pragma mark - Table view data source (表视图数据源)
103
104 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {105 //#warning Potentially incomplete method implementation.106 //Return the number of sections.107
108 //创建一个分区
109 return 1;110 }111
112 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {113 //#warning Incomplete method implementation.114 //Return the number of rows in the section.115
116 //分区中成员个数
117 returnself.dataSourceArr.count;118 }119
120 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {121
122 //根据下标取出相对应的cell
123 CellViewModel *cellModel =self.dataSourceArr[indexPath.row];124
125 return[CellTableViewCell cellHeight:cellModel];126 }127
128 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {129
130 //使用据有identifier标示的方法,在重用池中取值
131 CellTableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:kCellTabelViewCell forIndexPath:indexPath];132
133 //根据数组下标取出对应的CellViewModel类型的数据
134 CellViewModel *cellModel =self.dataSourceArr[indexPath.row];135
136 //将CellViewModel对象中的值传入CellTableViewCell类型对象
137 [cell passValue:cellModel];138
139 returncell;140 }141
142 @end
CellViewModel.h
1 #import
2 #import //Foundationg框架下无法使用UIKit框架下的内容,在这里引入UIKit框架; 注意引入系统文件使用<>
3
4 @interfaceCellViewModel : NSObject5
6 //创建控件,这里空间名称要与要取出的数据的key相同,这样使用kvc赋值的时候才能成功
7 @property (nonatomic , copy) NSString *title;8
9 @property (nonatomic , copy) NSString *summary;10
11 @end
CellViewModel.m
1 #import "CellViewModel.h"
2
3 @implementationCellViewModel4
5 - (void)dealloc6 {7 self.title =nil;8
9 self.summary =nil;10
11 [super dealloc];12 }13
14 //防止未找到对应的key值而crash,需要写一下下面的对象
15 -(void)setValue:(id)value forUndefinedKey:(NSString *)key {16
17 //里面可以什么都不写18 //NSLog(@"%@ -- %@" , key , value);
19 }20 @end
CellTableViewCell.h
1 #import
2 @classCellViewModel;3
4 @interfaceCellTableViewCell : UITableViewCell5
6 #pragma mark - 创建一个类返回cell的高度
7 + (CGFloat)cellHeight:(CellViewModel *)cellViewModel;8
9 #pragma mark - 创建一个接口,让外部可以通过这个接口传值
10 -(void)passValue:(CellViewModel *)cellViewModel;11
12 @end
CellTableViewCell.m
1 #import "CellTableViewCell.h"
2 #import "CellViewModel.h"
3
4 @interfaceCellTableViewCell ()5
6 //创建标题Label视图
7 @property (nonatomic , retain) UILabel *titleLabel;8
9 //创建摘要Label视图
10 @property (nonatomic , retain) UILabel *summaryLabel;11
12 @end
13
14 @implementationCellTableViewCell15
16
17 - (void)dealloc18 {19 self.titleLabel =nil;20
21 self.summaryLabel =nil;22
23 [super dealloc];24 }25
26
27 #pragma mark - 创建属性的懒加载方式
28 //懒加载方式的创建步骤29 //1. 必须有属性30 //2. 重写属性的getter方法,如果为空那么就创建, 如果有就直接使用31 //好处: 1. 真正使用的时候采取创建它,有效的降低了内存 2. 通过懒加载能够有效的分隔代码块
32
33 -(UILabel *)titleLabel {34
35 if (!_titleLabel) {36
37 self.titleLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 30)] autorelease];38
39 //此处最好不要使用self.的方法,因为self.属于getter方法,getter方法中不能套用getter方法,不然就会无限调用40 //设置背景色用于观察控件位置41 //_titleLabel.backgroundColor = [UIColor redColor];
42 }43 //安全释放
44 return[[_titleLabel retain] autorelease];45 }46
47 -(UILabel *)summaryLabel {48
49 if (!_summaryLabel) {50 self.summaryLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 50, 300, 30)] autorelease];51
52 _summaryLabel.numberOfLines = 0; //行数设置为0,指的就是文字内容自动适应宽度(自动换行);53
54 //设置背景色用于观察控件位置55 //_summaryLabel.backgroundColor = [UIColor redColor];56
57 //设置label文字大小
58 _summaryLabel.font = [UIFont systemFontOfSize:15.0];59 }60
61 //安全释放
62 return[[_summaryLabel retain] autorelease];63 }64
65
66 #pragma mark - 创建一个类返回summary文字内容的总高度
67 + (CGFloat)summaryHeight:(CellViewModel *)cellViewModel {68
69 //CGRect rect = [cellViewModel.summary boundingRectWithSize: options: attributes: context:]70 //
71 //return rect.size.height;72 //上面方法可以返回文字的宽度高度: 需要提供一个CGSize, NSStringDrawingOptions, NSDictionary对象73 //1. 绘制文本大小,这里要和summary一样宽,但是到不不用管
74 CGSize contentSize = CGSizeMake(300, 0); //这里只需提供宽度就可以了75
76 //2. 设置文本绘制标准(使用系统提供)77
78 //3. 设置文字属性(注意: 文字的大小要和summaryLabel设置的保持一致)
79 NSDictionary *dic = @{NSFontAttributeName : [UIFont boldSystemFontOfSize:15.0]};80
81 //返回文本rect
82 CGRect rect =[cellViewModel.summary boundingRectWithSize:contentSize options:(NSStringDrawingUsesLineFragmentOrigin) attributes:dic context:nil];83
84 returnrect.size.height;85 }86
87
88 #pragma mark - 创建一个类返回cell的高度
89 + (CGFloat)cellHeight:(CellViewModel *)cellViewModel {90
91 //self在类方法中使用,代表的就是类, 在对象方法中代表的就是对象
92 return 10 + 30 + 10 +[self summaryHeight:cellViewModel];93 }94
95 #pragma mark - 创建一个接口,让外部可以通过这个接口传值
96 -(void)passValue:(CellViewModel *)cellViewModel {97
98 //将model中的值赋值给titleLabel
99 self.titleLabel.text =cellViewModel.title;100
101 //将model中的值赋值给summaryLabel
102 self.summaryLabel.text =cellViewModel.summary;103
104 //让_summary的高度变化适应文字内容105 //_summaryLabel.frame = CGRectMake(10, 50, [[self class] summaryHeight:cellViewModel], 300);106
107 //在对象方法中由于self代表的是对象,所以要进行一下转换108 //[self class] 返回一个类
109 CGFloat height = [[self class] summaryHeight:cellViewModel];110
111 CGRect sFrame =self.summaryLabel.frame;112
113 sFrame.size.height =height;114
115 self.summaryLabel.frame =sFrame;116 }117
118
119 #pragma mark - 重写初始化将titleLabel和summaryLabel添加到表视图的contentView上
120 -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {121
122 //判断父类是否初始化
123 if (self =[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {124
125 [self.contentView addSubview:self.titleLabel]; //这里必须使用self.的方式调用属性,不能使用_的方式
126
127 [self.contentView addSubview:self.summaryLabel];128 }129
130 returnself;131 }132
133 - (void)awakeFromNib {134 //Initialization code
135 }136
137 - (void)setSelected:(BOOL)selected animated:(BOOL)animated {138 [super setSelected:selected animated:animated];139
140 //Configure the view for the selected state
141 }142
143 @end