标签:
通过MVC的设计模式,设计微博界面
1.M--Model
1)数据Model
1>声明
#import <Foundation/Foundation.h>
@interface CZStatus : NSObject
// 用户头像
@property (nonatomic, copy) NSString *icon;
// 用户名
@property (nonatomic, copy) NSString *name;
// 会员
@property (nonatomic, assign) BOOL isVip;
// 微博内容
@property (nonatomic, copy) NSString *text;
// 配图
@property (nonatomic, copy) NSString *picture;
+ (instancetype)statusWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;
@end
2>实现
#import "CZStatus.h"
@implementation CZStatus
+ (instancetype)statusWithDict:(NSDictionary *)dict {
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
@end
2)每一行cell的frame的model
1>声明
#import <UIKit/UIKit.h>
@class CZStatus;
/// 用户名字体大小
#define nameLabelFont [UIFont systemFontOfSize:14.0]
/// 微博文字字体大小
#define textLabelFont [UIFont systemFontOfSize:15.0]
@interface CZStatusFrame : NSObject
// 数据模型
@property (nonatomic, strong) CZStatus *status;
/**
* 头像frame
*/
@property (nonatomic, assign, readonly) CGRect iconF;
/**
* 昵称frame
*/
@property (nonatomic, assign, readonly) CGRect nameF;
/**
* vip图标frame
*/
@property (nonatomic, assign, readonly) CGRect vipF;
/**
* 正文frame
*/
@property (nonatomic, assign, readonly) CGRect textF;
/**
* 配图的frame
*/
@property (nonatomic, assign, readonly) CGRect picF;
/**
* cell的行高
*/
@property (nonatomic, assign, readonly) CGFloat cellHeight;
@end
2>实现
#import "CZStatusFrame.h"
#import "CZStatus.h"
#define Spacing 8
@implementation CZStatusFrame
// 重写数据模型的set方法,在此方法计算子控件的frame和行高
- (void)setStatus:(CZStatus *)status {
#warning mark - 重写set方法一定不要忘了给下线线的成员变量赋值
_status = status;
// 头像
CGFloat iconX = Spacing;
CGFloat iconY = Spacing;
CGFloat iconW = 35;
CGFloat iconH = iconW;
_iconF = CGRectMake(iconX, iconY, iconW, iconH);
// 昵称
CGFloat nameLX = CGRectGetMaxX(_iconF) + Spacing;
CGFloat nameLY = iconY + Spacing;
CGSize nameSize = [self sizeWithText:_status.name font:nameLabelFont maxSize: CGSizeMake(MAXFLOAT, MAXFLOAT)];
_nameF = (CGRect){{nameLX, nameLY}, nameSize};
// vip图标
if (_status.isVip) {
CGFloat vipX = CGRectGetMaxX(_nameF) + Spacing;
CGFloat vipY = nameLY + Spacing * 0.3;
CGFloat vipW = 15;
CGFloat vipH = 15;
_vipF = CGRectMake(vipX, vipY, vipW, vipH);
}
// 正文
CGFloat textX = iconX;
CGFloat textY = CGRectGetMaxY(_iconF) + Spacing;
CGFloat textMaxWidth = [UIScreen mainScreen].bounds.size.width - 2 *Spacing;
CGSize textSize = [self sizeWithText:_status.text font:textLabelFont maxSize:CGSizeMake(textMaxWidth, MAXFLOAT)];
_textF = (CGRect){{textX, textY}, textSize};
// 配图
if (_status.picture) {
CGFloat picX = iconX;
CGFloat picY = CGRectGetMaxY(_textF) + Spacing;
CGFloat picW = 100;
CGFloat picH = picW;
_picF = CGRectMake(picX, picY, picW, picH);
}
_cellHeight = MAX(CGRectGetMaxY(_picF), CGRectGetMaxY(_textF)) + Spacing;
}
/**
* 计算文字尺寸
*
* @param text 需要计算的文字
* @param font 文字字体
* @param maxSize 文字矩形最大尺寸
*/
- (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize {
NSDictionary *attributes = @{NSFontAttributeName : font};
return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;
}
@end
2.V--View 即视图
cell视图
1)声明
#import <UIKit/UIKit.h>
@class CZStatusFrame;
@interface CZStatusCell : UITableViewCell
// frame模型
@property (nonatomic, strong) CZStatusFrame *statusFrame;
+ (instancetype)cellWithTableView:(UITableView *)tableView;
@end
2)实现
#import "CZStatusCell.h"
#import "CZStatus.h"
#import "CZStatusFrame.h"
#define Margins 8
@interface CZStatusCell ()
@property (nonatomic, strong) CZStatus *status;
@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 CZStatusCell
/// 快速创建cell
+ (instancetype)cellWithTableView:(UITableView *)tableView {
static NSString *ID = @"cell";
CZStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[CZStatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
return cell;
}
// 重写initWithStyle:方法,让cell一创建出来就已经有多有子控件
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// 添加cell的内部子控件
[self addStatusCellWithSubview];
}
return self;
}
// 添加cell的内部子控件
- (void)addStatusCellWithSubview {
// 头像
self.iconView = [self createImageView];
// 昵称
self.nameView = [self createLabelWithFont:nameLabelFont];
// vip图标
self.vipView = [self createImageView];
self.vipView.image = [UIImage imageNamed:@"vip"];
// 正文
self.textView = [self createLabelWithFont:textLabelFont];
// 配图
self.pictureView = [self createImageView];
}
/// 快速创建并添加label
- (UILabel *)createLabelWithFont:(UIFont *)font {
UILabel *label = [[UILabel alloc] init];
label.numberOfLines = 0;
label.font = font;
[self.contentView addSubview:label];
return label;
}
/// 快速创建并添中imageView
- (UIImageView *)createImageView {
UIImageView *imageView = [[UIImageView alloc] init];
[self.contentView addSubview:imageView];
return imageView;
}
/// 重写frame模型的set方法,在此方法设置cell子控件的数据和frame
- (void)setStatusFrame:(CZStatusFrame *)statusFrame {
_statusFrame = statusFrame;
_status = statusFrame.status;
// 1.设置数据
[self settingData];
// 2.计算frame
[self settingFrame];
}
// 设置控件数据
- (void)settingData {
// 设置用户头像
self.iconView.image = [UIImage imageNamed:_status.icon];
// 设置用户名
self.nameView.text = _status.name;
// 设置用户名颜色,会员是红色,普通用户是黑色
self.nameView.textColor = _status.isVip ? [UIColor redColor] : [UIColor blackColor];
// 是否显示会员
self.vipView.hidden = _status.isVip ? NO : YES;
// 设置微博内容
self.textView.text = _status.text;
// 是否显示配图
self.pictureView.hidden = _status.picture ? NO : YES;
// 设置配图
self.pictureView.image = _status.picture ? [UIImage imageNamed:_status.picture] : nil;
}
/// 设置控件frame
- (void)settingFrame {
// 设置用户头像frame
self.iconView.frame = self.statusFrame.iconF;
// 设置用户名frame
self.nameView.frame = self.statusFrame.nameF;
// 设置vip的frame
self.vipView.frame = _status.isVip ? self.statusFrame.vipF : CGRectZero;
// 设置微博内容的frame
self.textView.frame = self.statusFrame.textF;
// 设置配图的frame
self.pictureView.frame = _status.picture ? self.statusFrame.picF : CGRectZero;
}
@end
3.C--Controller 即控制层
1)声明
#import <UIKit/UIKit.h>
@interface CZViewController : UITableViewController // 此处继承自UITableViewController
@end
2)实现
#import "CZViewController.h"
#import "CZStatus.h"
#import "CZStatusCell.h"
#import "CZStatusFrame.h"
@interface CZViewController ()
@property (nonatomic, strong) NSArray *statusFrame;
@end
@implementation CZViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 预估行高
self.tableView.estimatedRowHeight = 300;
}
// 隐藏状态栏
- (BOOL)prefersStatusBarHidden {
return YES;
}
#pragma mark - tableView的数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.statusFrame.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 创建cell
CZStatusCell *cell = [CZStatusCell cellWithTableView:tableView];
// 拿到每行对应的frame模型
CZStatusFrame *statusFrame = self.statusFrame[indexPath.row];
// 给cell的frame模型赋值
cell.statusFrame = statusFrame;
return cell;
}
#pragma mark - 代理方法用来返回行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// 返回cell的高度
return [self.statusFrame[indexPath.row] cellHeight];
}
// 懒加载字典转模型
- (NSArray *)statusFrame {
if (_statusFrame == nil) {
NSArray *dictArr = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil]];
NSMutableArray *arrM = [NSMutableArray array];
[dictArr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
CZStatusFrame *statusFrame = [[CZStatusFrame alloc] init];
CZStatus *status = [CZStatus statusWithDict:obj];
statusFrame.status = status;
[arrM addObject:statusFrame];
}];
_statusFrame = arrM;
}
return _statusFrame;
}
@end
标签:
原文地址:http://www.cnblogs.com/wangdjblogs/p/5515856.html