今天给同学讲解一下微博的展示不同的行高,以及一种新的模式!那么废话不多说,直接上代码~
通过代码自定义cell
1> 新建一个继承自UITableViewCell的类
2> 先在initWithStyle:初始化在将有可能显示的子控件全部添加进来
3> 提供一个模型属性
4> 重写模型属性的setter方法
5> 设置数据模块不一定每个地方都是一样的 如果设置了 hidden 的地方一定要设置相反的设置回来
6> 循环利用一个致命的缺点 一定要保证所有的状态和数据全部被换掉所以有YES的地方一样要有NO 并且设置的数据一定要覆盖并且清楚尤其状态
7> 设置固定死的数据那么我们只需要进行一次性设置那么写在初始化的方法中就足够因为写来写去都只会
8> cell行高 必须要拿到每一行cell内部的高度 才能计算cell的高度 可是系统调用方法导致这一点不可能!先得拿到全部的行高才能设置数据显示数据!那么问题来了 我们不能拿到 所以我们只能够在加载数据的时候就算好高度 然后给需要的地方用!
9> 封装frame模型的思想 并且只是readonly的 因为是readonly 所以没有生成setter方法 不能通过点语法访问 只能_XXXX
//
// ZZStatus.h
// 08-简单微博展示
//
// Created by 周昭 on 16/12/6.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ZZStatus : NSObject
/**
* 图标
*/
@property (nonatomic,copy) NSString *icon;
/**
* 姓名
*/
@property (nonatomic,copy) NSString *name;
/**
* vip
*/
@property (nonatomic,assign) BOOL vip;
/**
* 正文
*/
@property (nonatomic,copy) NSString *text;
/**
* 配图
*/
@property (nonatomic,copy) NSString *picture;
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)statusWithDict:(NSDictionary *)dict;
@end
//
// ZZStatus.m
// 08-简单微博展示
//
// Created by 周昭 on 16/12/6.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZStatus.h"
@implementation ZZStatus
- (instancetype)initWithDict:(NSDictionary *)dict;
{
if (self = [superinit]) {
#warning - 那么这里同学们肯定很困惑BOOL类型和NSNumber不一致 KVC就是这么强大直接转换
[selfsetValuesForKeysWithDictionary:dict];
}
returnself;
}
+ (instancetype)statusWithDict:(NSDictionary *)dict
{
return [[selfalloc] initWithDict:dict];
}
@end
//
// ZZStatusFrame.h
// 08-简单微博展示
//
// Created by 周昭 on 16/12/6.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class ZZStatus;
@interface ZZStatusFrame : NSObject
#warning - 这里写了readonly和不写那差别就很大了自己封装好的一个类计算好了直接给同事拿去用那就肯定不希望同事乱改这么写了一看就是大神有团队合作的经验所以要理解更要养成好的习惯
/**
* 头像的frame
*/
@property (nonatomic,assign, readonly)CGRect iconF;
/**
* 昵称的frame
*/
@property (nonatomic,assign, readonly)CGRect nameF;
/**
* 会员的frame
*/
@property (nonatomic,assign, readonly)CGRect vipF;
/**
* 正文的frame
*/
@property (nonatomic,assign, readonly)CGRect textF;
/**
* 配图的frame
*/
@property (nonatomic,assign, readonly)CGRect pictureF;
/**
* 每个cell的高度
*/
@property (nonatomic,assign, readonly)CGFloat cellHeight;
/**
* 微博模型
*/
@property (nonatomic,strong) ZZStatus *status;
@end
//
// ZZStatusFrame.m
// 08-简单微博展示
//
// Created by 周昭 on 16/12/6.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#define NameFont [UIFont systemFontOfSize:14.0f]
#define TextFont [UIFont systemFontOfSize:15.0f]
#import "ZZStatusFrame.h"
#import "ZZStatus.h"
@implementation ZZStatusFrame
/**
* 重写setter方法计算子控件的frame&cell的高度
*/
- (void)setStatus:(ZZStatus *)status
{
_status = status;
CGFloat padding =10;
#warning - 封装frame模型的思想并且只是readonly的因为是readonly所以没有生成setter方法不能通过点语法访问只能_XXXX
CGFloat iconX = padding;
CGFloat iconY = padding;
CGFloat iconW =35;
CGFloat iconH = iconW;
_iconF =CGRectMake(iconX, iconY, iconW, iconH);
CGSize nameSize = [selfsizeWithText:status.namefont:NameFontmaxSize:CGSizeMake(MAXFLOAT,MAXFLOAT)];
CGFloat nameX =CGRectGetMaxX(_iconF) + padding;
CGFloat nameW = nameSize.width;
CGFloat nameH = nameSize.height;
CGFloat nameY = iconY + (iconH - nameH) *0.5;
_nameF =CGRectMake(nameX, nameY, nameW, nameH);
if (status.vip) {
CGFloat vipX =CGRectGetMaxX(_nameF) + padding;
CGFloat vipY = nameY;
CGFloat vipW =14;
CGFloat vipH =14;
_vipF =CGRectMake(vipX, vipY, vipW, vipH);
}
CGSize textSize = [selfsizeWithText:status.textfont:TextFontmaxSize:CGSizeMake([UIScreenmainScreen].bounds.size.width - 2 * padding, MAXFLOAT)];
CGFloat textX = iconX;
CGFloat textY =CGRectGetMaxY(_iconF) + padding;
CGFloat textW = textSize.width;
CGFloat textH = textSize.height;
_textF =CGRectMake(textX, textY, textW, textH);
if (status.picture) {
CGFloat pictureX = iconX;
CGFloat pictureY =CGRectGetMaxY(_textF) + padding;
CGFloat pictureW =100;
CGFloat pictureH = pictureW;
_pictureF =CGRectMake(pictureX, pictureY, pictureW, pictureH);
_cellHeight =CGRectGetMaxY(_pictureF);
} else {
_cellHeight =CGRectGetMaxY(_textF);
}
}
/**
* 计算文字尺寸
*
* @param text 需要计算尺寸的文字
* @param font 字体
* @param maxSize 文字的最大尺寸
*
* @return 返回CGSize对象
*/
- (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize
{
NSDictionary *attrs =@{NSFontAttributeName : font};
return [textboundingRectWithSize:maxSizeoptions:NSStringDrawingUsesLineFragmentOriginattributes:attrs context:nil].size;
}
@end
//
// ZZStatusCell.h
// 08-简单微博展示
//
// Created by 周昭 on 16/12/6.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#define NameFont [UIFont systemFontOfSize:14.0f]
#define TextFont [UIFont systemFontOfSize:15.0f]
#import <UIKit/UIKit.h>
@class ZZStatusFrame;
@interface ZZStatusCell : UITableViewCell
@property (nonatomic,strong) ZZStatusFrame *statusFrame;
+ (instancetype)cellWithTableView:(UITableView *)tableView;
@end
//
// ZZStatusCell.m
// 08-简单微博展示
//
// Created by 周昭 on 16/12/6.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZStatusCell.h"
#import "ZZStatusFrame.h"
#import "ZZStatus.h"
@interface ZZStatusCell()
/**
* 图标
*/
@property (nonatomic,weak) UIImageView *iconView;
/**
* 昵称
*/
@property (nonatomic,weak) UILabel *nameView;
/**
* 会员
*/
@property (nonatomic,weak) UIImageView *vipView;
/**
* 正文
*/
@property (nonatomic,weak) UILabel *textView;
/**
* 配图
*/
@property (nonatomic,weak) UIImageView *pictureView;
@end
@implementation ZZStatusCell
+ (instancetype)cellWithTableView:(UITableView *)tableView
{
staticNSString *ID = @"status";
ZZStatusCell *cell = [tableViewdequeueReusableCellWithIdentifier:ID];
if (cell ==nil) {
cell = [[ZZStatusCellalloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:ID];
}
return cell;
}
#warning - 重写这个方法只在这个方法中进行所有控件的加载并且进行一次性初始化设置(不能设置数据和frame不要傻逼这里拿不到)
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [superinitWithStyle:style reuseIdentifier:reuseIdentifier]) {
// 1.图标
UIImageView *iconView = [[UIImageViewalloc] init];
[self.contentViewaddSubview:iconView];
self.iconView = iconView;
// 2.昵称
UILabel *nameView = [[UILabelalloc] init];
nameView.font =NameFont;
[self.contentViewaddSubview:nameView];
self.nameView = nameView;
// 3.会员
UIImageView *vipView = [[UIImageViewalloc] init];
vipView.image = [UIImageimageNamed:@"vip"];
[self.contentViewaddSubview:vipView];
self.vipView = vipView;
// 4.正文
UILabel *textView = [[UILabelalloc] init];
textView.font =TextFont;
textView.numberOfLines =0;
[self.contentViewaddSubview:textView];
self.textView = textView;
// 5.配图
UIImageView *pictureView = [[UIImageViewalloc] init];
[self.contentViewaddSubview:pictureView];
self.pictureView = pictureView;
}
returnself;
}
- (void)setStatusFrame:(ZZStatusFrame *)statusFrame
{
_statusFrame = statusFrame;
// 1.设置数据
[selfsettingData];
// 2.设置frame
[selfsettingFrame];
}
- (void)settingData
{
// 0.拿出数据模型
ZZStatus *status =self.statusFrame.status;
// 1.设置头像的数据
self.iconView.image = [UIImageimageNamed:status.icon];
// 2.设置昵称
self.nameView.text = status.name;
// 3.设置会员
#warning - 如果是会员我们才需要设置\那么就用hidden属性来控制显示和隐藏如果设置了 YES那么必须设置 NO循环引用大家必须思考
if (status.vip) {
self.vipView.hidden =NO;
self.nameView.textColor = [UIColorredColor];
} else {
self.vipView.hidden =YES;
self.nameView.textColor = [UIColorblackColor];
}
// 4.设置正文
self.textView.text = status.text;
// 5.设置配图
if (status.picture) {
self.pictureView.hidden =NO;
self.pictureView.image = [UIImageimageNamed:status.picture];
} else {
self.pictureView.hidden =YES;
}
}
- (void)settingFrame
{
// 1.头像
self.iconView.frame =self.statusFrame.iconF;
// 2.昵称
self.nameView.frame =self.statusFrame.nameF;
// 3.会员
self.vipView.frame =self.statusFrame.vipF;
// 4.正文
self.textView.frame =self.statusFrame.textF;
// 5.配图
if (self.statusFrame.status.picture) { // 有配图才需要设置
self.pictureView.frame =self.statusFrame.pictureF;
}
}
@end
//
// ZZTableViewController.h
// 08-简单微博展示
//
// Created by 周昭 on 16/12/6.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ZZTableViewController :UITableViewController
@end
//
// ZZTableViewController.m
// 08-简单微博展示
//
// Created by 周昭 on 16/12/6.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZTableViewController.h"
#import "ZZStatusFrame.h"
#import "ZZStatus.h"
#import "ZZStatusCell.h"
@interface ZZTableViewController()
/**
* 存放所有的微博模型\微博frame模型&数据模型
*/
@property (nonatomic,strong) NSArray *statusFrames;
@end
@implementation ZZTableViewController
- (NSArray *)statusFrames
{
if (_statusFrames ==nil) {
// 1.获得plist的全路径
NSString *path = [[NSBundlemainBundle] pathForResource:@"statuses.plist"ofType:nil];
// 2.加载数组
NSArray *dictArr = [NSArrayarrayWithContentsOfFile:path];
// 3.将dictArr中所有的字典转成模型对象,放到新的数组中
NSMutableArray *statusFrameArr = [NSMutableArrayarray];
for (NSDictionary *dictin dictArr) {
// 3.1创建模型对象
ZZStatus *status = [ZZStatusstatusWithDict:dict];
// 3.2创建statusFrame模型对象
ZZStatusFrame *statusFrame = [[ZZStatusFramealloc] init];
statusFrame.status = status;
// 3.2添加模型对象到数组中
[statusFrameArr addObject:statusFrame];
}
// 4.赋值
_statusFrames = statusFrameArr;
}
return_statusFrames;
}
#pragma mark - tableView数据源和代理方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
returnself.statusFrames.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.创建cell
ZZStatusCell *cell = [ZZStatusCellcellWithTableView:tableView];
// 2.给cell传递数据模型
cell.statusFrame =self.statusFrames[indexPath.row];
// 3.返回cell
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
ZZStatusFrame *statusFrame =self.statusFrames[indexPath.row];
return statusFrame.cellHeight;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPathanimated:YES];
}
@end