cell高度自动适应文章内容

效果:

描述:表视图中生成多个不同的cell,cell的高度跟文字内容的多少有关

要求:需要自己在网上下载一个plis文件,然后修改两个标题

一 : 创建工程文件UIAutomaticCellHeightPractce-11

二 : 这里使用手动释放,所以需要修改工程文件Automatic Reference Counting 修改为NO

三 : 修改引用计数方式

 

四 : 释放适量变量,以及对父集进行释放,并让自动释放self.window(autorelease)

五 : 导入.plist文件(直接拖进工程文件)

六 : 工程文件

七 :代码区(采用MVC的设计模式)

模型-视图-控制器(Model-View-Controller,MVC)

AppDelegate.h

1 #import <UIKit/UIKit.h>
2 
3 @interface AppDelegate : UIResponder <UIApplicationDelegate>
4 
5 @property (retain, nonatomic) UIWindow *window;
6 
7 
8 @end

AppDelegate.m

 1 #import "AppDelegate.h"
 2 #import "RootTableViewController.h"
 3 
 4 @interface AppDelegate ()
 5 
 6 @end
 7 
 8 @implementation AppDelegate
 9 
10 - (void)dealloc
11 {
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     return YES;
34 }
35 
36 @end

RootTableViewController.h

1 #import <UIKit/UIKit.h>
2 
3 @interface RootTableViewController : UITableViewController
4 
5 @end

RootTableViewController.m

  1 #import "RootTableViewController.h"
  2 #import "CellViewModel.h"
  3 #import "CellTableViewCell.h"
  4 #define kCellTabelViewCell @"cell"
  5 
  6 @interface RootTableViewController ()
  7 
  8 // 创建公用数组
  9 @property (nonatomic , retain) NSMutableArray *dataSourceArr;
 10 
 11 @end
 12 
 13 @implementation RootTableViewController
 14 
 15 - (void)dealloc
 16 {
 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 in arr) {
 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     return self.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     return cell;
140 }
141 
142 @end

CellViewModel.h

 1 #import <Foundation/Foundation.h>
 2 #import <UIKit/UIKit.h> // Foundationg框架下无法使用UIKit框架下的内容,在这里引入UIKit框架; 注意引入系统文件使用<>
 3 
 4 @interface CellViewModel : NSObject
 5 
 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 @implementation CellViewModel
 4 
 5 - (void)dealloc
 6 {
 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 <UIKit/UIKit.h>
 2 @class CellViewModel;
 3 
 4 @interface CellTableViewCell : UITableViewCell
 5 
 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 @interface CellTableViewCell ()
  5 
  6 // 创建标题Label视图
  7 @property (nonatomic , retain) UILabel *titleLabel;
  8 
  9 // 创建摘要Label视图
 10 @property (nonatomic , retain) UILabel *summaryLabel;
 11 
 12 @end
 13 
 14 @implementation CellTableViewCell
 15 
 16 
 17 - (void)dealloc
 18 {
 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:<#(CGSize)#> options:<#(NSStringDrawingOptions)#> attributes:<#(NSDictionary *)#> context:<#(NSStringDrawingContext *)#>]
 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     return rect.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     return self;
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

 

posted @ 2015-12-14 19:23  li625317534  阅读(318)  评论(0编辑  收藏  举报