***********

#import "HMViewController.h"
#import "HMStatus.h"
#import "HMStatusCell.h"
#import "HMStatusFrame.h" @interface HMViewController ()
/** 保存statusFrame模型的数组 */
@property (nonatomic, strong) NSArray *statusFrames;
@end @implementation HMViewController
static NSString *ID = @"Cell"; - (NSArray *)statusFrames
{
if (_statusFrames == nil) _statusFrames = [HMStatusFrame statusFrames];
return _statusFrames;
} // 界面创建完成被调用
- (void)viewDidLoad
{
[super viewDidLoad]; // 为tableView注册可重用单元格
[self.tableView registerClass:[HMStatusCell class] forCellReuseIdentifier:ID];
} #pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.statusFrames.count;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/**
在Storyboard中指定了可重用标示符,同时指定了Cell的类是HMStatusCell 系统会为tableView注册一个原形Cell,专门用来做可重用单元格的,一旦缓冲区中不存在
可重用单元格,系统会使用原形Cell新实例化一个Cell用程序使用! 因此如果在,Storyboard中,注册了原形Cell,就不再需要 cell == nil的判断了
*/
// HMStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard
// 使用这个方法,要求一定注册可重用单元格,否则就会崩溃!
// 官方建议使用以下方法,利用程序的崩溃,及时发现问题
HMStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];
// 一旦在注册了可重用Cell,以上两个方法是等价的 // if (cell == nil) {
// cell = [[HMStatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
// } // 赋值
// 取出StatusFrame模型
HMStatusFrame *statusFrame = self.statusFrames[indexPath.row];
cell.statusFrame = statusFrame; return cell;
} #pragma mark - 代理方法
/** 计算单元格行高 */
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
/**
计算行高的方法,会在加载表格数据时,有多少行计算多少次 contentSize 问题:此方法执行的时候,cell还没有被实例化!
但是:行高计算是在实例化cell时,通过设置status属性,计算的=>有了status模型,就可以知道行高! 问题:如何在cell实例化之前,获得行高?
解决方法:通过status可以计算得到行高!=》再建立一个模型,专门计算所有控件的位置
*/
HMStatusFrame *statusFrame = self.statusFrames[indexPath.row]; return statusFrame.cellHeight;
} @end

********modol.h

#import <Foundation/Foundation.h>
@class HMStatus; /** 专门计算所有控件位置 */
@interface HMStatusFrame : NSObject
@property (nonatomic, assign) CGRect iconF;
@property (nonatomic, assign) CGRect nameF;
@property (nonatomic, assign) CGRect vipF;
@property (nonatomic, assign) CGRect textF;
@property (nonatomic, assign) CGRect pictureF; /** 行高 */
@property (nonatomic, assign) CGFloat cellHeight; /** 所有控件的尺寸都可以通过Status来计算得出 */
@property (nonatomic, strong) HMStatus *status; /** 所有的statusFrame数据数组 */
+ (NSArray *)statusFrames; @end

****************

#import "HMStatusFrame.h"
#import "HMStatus.h"
#import "NSString+Tools.h" /** 姓名字体 */
#define kNameFont [UIFont systemFontOfSize:14]
/** 正文字体 */
#define kTextFont [UIFont systemFontOfSize:16] @implementation HMStatusFrame
//@synthesize iconF = _iconF; /**
一旦重写了readonly属性的getter方法,_的成员变量就不存在了 如果还需要使用_成员变量,则需要使用@synthesize生成对应的成员变量
*/
//- (CGRect)iconF
//{
//
//} - (void)setStatus:(HMStatus *)status
{
_status = status; // 0. 定义间距
CGFloat padding = ; // 1. 头像
CGFloat iconX = padding;
CGFloat iconY = padding;
CGFloat iconW = ;
CGFloat iconH = ;
_iconF = CGRectMake(iconX, iconY, iconW, iconH); // 2. 姓名大小由文字的长度来决定
// boundingRectWithSize计算给定文本字符串所占的区域
// 返回值是一个x,y = 0的CGRect,w,h是计算好的宽高
//
// 如果要计算多行的准确高度,需要传入NSStringDrawingUsesLineFragmentOrigin选项
// dict用于指定字体的相关属性的字典,UIKit框架中的第一个头文件
// context: nil
NSDictionary *nameDict = @{NSFontAttributeName: kNameFont};
// CGRect nameFrame = [self.status.name boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:nameDict context:nil];
CGRect nameFrame = [self.status.name textRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) attributes:nameDict]; nameFrame.origin.x = CGRectGetMaxX(self.iconF) + padding;
nameFrame.origin.y = padding + (self.iconF.size.height - nameFrame.size.height) * 0.5;
_nameF = nameFrame; // vip图标
CGFloat vipX = CGRectGetMaxX(self.nameF) + padding;
CGFloat vipY = self.nameF.origin.y;
CGFloat vipW = ;
CGFloat vipH = ;
_vipF = CGRectMake(vipX, vipY, vipW, vipH); // 正文
NSDictionary *textDict = @{NSFontAttributeName: kTextFont};
// CGRect textFrame = [self.status.text boundingRectWithSize:CGSizeMake(300, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:textDict context:nil];
CGRect textFrame = [self.status.text textRectWithSize:CGSizeMake(, MAXFLOAT) attributes:textDict]; textFrame.origin.x = padding;
textFrame.origin.y = CGRectGetMaxY(self.iconF) + padding;
_textF = textFrame; if (self.status.picture.length > ) {
// 配图
CGFloat pictureX = padding;
CGFloat pictureY = CGRectGetMaxY(textFrame) + padding;
CGFloat pictureW = ;
CGFloat pictureH = ;
_pictureF = CGRectMake(pictureX, pictureY, pictureW, pictureH); _cellHeight = CGRectGetMaxY(self.pictureF) + padding;
} else {
_cellHeight = CGRectGetMaxY(self.textF) + padding;
}
} + (NSArray *)statusFrames
{
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil]]; NSMutableArray *arrayM = [NSMutableArray array];
for (NSDictionary *dict in array) {
// 要添加statusFrame对象
HMStatusFrame *statusFrame = [[HMStatusFrame alloc] init]; // 实例化一个新的Status模型
HMStatus *status = [HMStatus statusWithDict:dict]; // 调用自己的setter方法,保存status数据模型,同时计算出所有控件的位置
statusFrame.status = status; // 将statusFrame添加到数组
[arrayM addObject:statusFrame];
} return arrayM;
} @end

*************cell.h

#import <UIKit/UIKit.h>
@class HMStatusFrame; @interface HMStatusCell : UITableViewCell
@property (nonatomic, strong) HMStatusFrame *statusFrame;
@end

*************cell.m

#import "HMStatusCell.h"
#import "HMStatus.h"
#import "HMStatusFrame.h" /** 姓名字体 */
#define kNameFont [UIFont systemFontOfSize:14]
/** 正文字体 */
#define kTextFont [UIFont systemFontOfSize:16] @interface HMStatusCell() @property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *nameView;
@property (nonatomic, strong) UIImageView *vipView;
@property (nonatomic, strong) UILabel *textView;
@property (nonatomic, strong) UIImageView *pictureView; @end @implementation HMStatusCell - (UIImageView *)iconView
{
if (_iconView == nil) {
_iconView = [[UIImageView alloc] init];
[self.contentView addSubview:_iconView];
}
return _iconView;
} - (UILabel *)nameView
{
if (_nameView == nil) {
_nameView = [[UILabel alloc] init];
// 默认字体是17号
_nameView.font = kNameFont;
[self.contentView addSubview:_nameView];
}
return _nameView;
} - (UIImageView *)vipView
{
if (_vipView == nil) {
_vipView = [[UIImageView alloc] init];
_vipView.image = [UIImage imageNamed:@"vip"];
_vipView.hidden = YES; [self.contentView addSubview:_vipView];
}
return _vipView;
} - (UILabel *)textView
{
if (_textView == nil) {
_textView = [[UILabel alloc] init];
_textView.font = kTextFont;
_textView.numberOfLines = ; [self.contentView addSubview:_textView];
}
return _textView;
} - (UIImageView *)pictureView
{
if (_pictureView == nil) {
_pictureView = [[UIImageView alloc] init];
[self.contentView addSubview:_pictureView];
}
return _pictureView;
} - (void)setStatusFrame:(HMStatusFrame *)statusFrame
{
_statusFrame = statusFrame; // 1> 设置数据
[self settingData]; // 2> 设置位置
[self settingFrame];
} /** 设置数据 */
- (void)settingData
{
HMStatus *status = self.statusFrame.status; // 头像
self.iconView.image = [UIImage imageNamed:status.icon];
// 姓名
self.nameView.text = status.name;
// vip(可选的)
if (status.vip) {
self.vipView.hidden = NO;
self.nameView.textColor = [UIColor redColor];
} else {
self.vipView.hidden = YES;
self.nameView.textColor = [UIColor blackColor];
} // 正文
self.textView.text = status.text; // 配图(可选参数)
// imageNamed:nil CUICatalog: Invalid asset name supplied: (null), or invalid scale factor: 2.000000
if (status.picture.length > ) {
self.pictureView.hidden = NO;
self.pictureView.image = [UIImage imageNamed:status.picture];
} else {
self.pictureView.hidden = YES;
}
} /** 设置位置 */
- (void)settingFrame
{
// 1. 头像
self.iconView.frame = self.statusFrame.iconF; // 2. 姓名大小由文字的长度来决定
self.nameView.frame = self.statusFrame.nameF; // vip图标
self.vipView.frame = self.statusFrame.vipF; // 正文
self.textView.frame = self.statusFrame.textF; // 配图
if (self.statusFrame.status.picture.length > ) {
self.pictureView.frame = self.statusFrame.pictureF;
}
} @end

IOS第八天(7:UITableViewController新浪微博,cell 复用的简单写法优化和cell高度从模型中获取)的更多相关文章

  1. IOS第八天(6:UITableViewController新浪微博, 模型和 控件位置封装一起statusFrame)

    *****HMViewController #import "HMViewController.h" #import "HMStatus.h" #import ...

  2. IOS第八天(4:UITableViewController新浪微博, 代码创建布局和数据转模型)

    ******控制control #import "HMViewController.h" #import "HMStatus.h" #import " ...

  3. IOS第八天(5:UITableViewController新浪微博, 计算行高)

    在 4 的 基础上重写 以下的方法 control #pragma mark - 代理方法 /** 计算单元格行高 */ - (CGFloat)tableView:(UITableView *)tab ...

  4. IOS第八天(2:UITableViewController团购,点击底部,xib加载更多, 代理模式)

    ******* HMViewController.h #import "HMViewController.h" #import "HMTg.h" #import ...

  5. IOS第八天(1:UITableViewController团购,数据转模型,xib显示数据)

    ******HMTg.h 模型数据 #import <Foundation/Foundation.h> @interface HMTg : NSObject @property (nona ...

  6. IOS第八天(3:UITableViewController团购, 点击底部代码调整)

    ****代理者的方法中 // 通知页脚视图调整视图显示状态 [footerView endRefresh]; //发送代理通知的类中 /** 视图控制器刷新完成调用方法 */ - (void)endR ...

  7. iOS programming UITableView and UITableViewController

    iOS programming  UITableView and UITableViewController A UITableView displays a single column of dat ...

  8. UITableView cell复用出错问题 页面滑动卡顿问题 & 各杂七杂八问题

    UITableView 的cell 复用机制节省了内存,但是有时对于多变的自定义cell,重用时会出现界面出错(例如复用出错,出现cell混乱重影).滑动卡顿等问题,这里只简单敲下几点复用出错时的解决 ...

  9. iOS开发——UI进阶篇(二)自定义等高cell,xib自定义等高的cell,Autolayout布局子控件,团购案例

    一.纯代码自定义等高cell 首先创建一个继承UITableViewCell的类@interface XMGTgCell : UITableViewCell在该类中依次做一下操作1.添加子控件 - ( ...

随机推荐

  1. 软件打开时间、窗体透明度、背景色---《用delphi开发共享软件》-15.1任务管理器

    1.计算软件启动了多长时间:用定时器,每分钟触发一次: procedure TFrmMain.tmCheckLegalTimer(Sender: TObject);Var Minutes:LongIn ...

  2. 【CLR in c#】属性

    1.无参属性 1.为什么有字段还需要属性呢? 因为字段很容易写出不恰当的代码,破坏对象的状态,比如Age=-1.人的年纪不可能为负数.使用属性后你可以缓存某些值或者推迟创建一些内部对象,你可以以线程安 ...

  3. Floyd_Warshall POJ 1847 Tram

    题目传送门 题意:这题题目难懂.问题是A到B最少要转换几次城市.告诉每个城市相连的关系图,默认与第一个之间相连,就是不用转换,其余都要转换. 分析:把第一个城市权值设为0, 其余设为0.然后Floyd ...

  4. IE下Array.prototype.slice.call(params,0)

    i8 不支持 Array.prototype.slice.call(params,0) params可以是 HTMLCollection.类数组.string字符串

  5. 编程之路 - 写给打算进入IT行业的新人们

    IT=挨踢,这是IT人的自嘲,进入IT行业是有四五年了,也算得上是一个“老人”了吧,见了不少新人,面试了不少新人,也带了一些新人,多多少少还是有点发言权的. 关于书本 新人们常常会说我看了多少多少的书 ...

  6. BZOJ2706 : [SDOI2012]棋盘覆盖

    A类数据: 将棋盘黑白染色,相邻的点之间连边,求出二分图最大匹配即可. B类数据: 答案为$\lfloor\frac{n^2-1}{3}\rfloor$,用FFT加速计算即可,时间复杂度$O(L\lo ...

  7. BZOJ4112 : [Wf2015]Pipe Stream

    枚举答案,考虑将速度区间等长地划分成若干个小区间. 设$n_i$表示$i$次敲击能得到的区间数,$v_i$表示$i$次敲击之后答案落在$[v1,v_i]$之间,则$n_0=1,v_0=v2$. 因为对 ...

  8. linux 远程桌面的配置

    root根用户登录在/root目录下#rpm -q vnc vnc-server查询已安装vnc的客户端和服务器端vnc-4.1.1-36vnc-server-4.1.1-36 #vi /etc/sy ...

  9. Excel中COUNTIFS函数统计词频个数出现次数

    Excel中COUNTIFS函数统计词频个数出现次数   在Excel中经常需要实现如下需求:在某一列单元格中有不同的词语,有些词语相同,有的不同(如图1所示).需要统计Excel表格中每个词语出现的 ...

  10. HDU-1231 简单dp,连续子序列最大和,水

    1.HDU-1231 2.链接:http://acm.hdu.edu.cn/showproblem.php?pid=1231 3.总结:水 题意:连续子序列最大和 #include<iostre ...