1、效果演示
2、更新说明
2.1 性能优化
2.2 增加微博详情的评论详情
2.3 增加微博详情的转发详情
3、设计说明
3.1 重构代码结构
3.1.1 重构数据模型
3.1.1.1 提取微博数据模型结构,增加根父类(SABaseText),根父类中实现基本数据模型转换,如头像、昵称、会员图标、创建时间、来源、正文
3.1.1.2 首页微博数据模型与微博详情数据模型属于同一类型直接继承根父类,增加相关数据内容(SAStatus)
3.1.1.3 转发数据模型与评论数据模型分别继承根父类,增加相关数据内容(SAComments、SAReports)
3.1.1.4 逻辑展示图:
3.1.2 重构数据框架模型
3.1.2.1 提取数据框架模型结构,增加根父类(SABaseTextCellFrame),根父类中实现基本数据框架模型,如头像、昵称、会员图标
3.1.2.2 首页微博数据框架模型与微博详情数据框架模型再提取父类(SABaseStatusCellFrame),直接继承根父类
3.1.2.3 首页微博数据框架模型继承SABaseStatusCellFrame,增加相关框架数据内容(SAHomeStatusCellFrame)
3.1.2.4 微博详情数据框架模型继承SABaseStatusCellFrame,增加相关框架数据内容(SAStatusDetailCellFrame)
3.1.2.5 转发数据框架模型与评论数据框架模型分别继承根父类,增加相关框架数据内容(SAReportFrame、SACommentFrame)
3.1.2.6 逻辑展示图:
3.1.3 重构UITableViewCell
3.1.3.1 提取各Cell基本结构,增加根父类(SABaseTextCell),根父类中实现基本Cell元素:头像、昵称、会员图标、创建时间、来源、正文
3.1.3.2 首页微博Cell与微博详情Cell再提取父类(SABaseStatusCell),直接继承根父类
3.1.3.3 首页微博Cell继承SABaseStatusCell,增加相关元素(SAHomeStatusCell)
3.1.3.4 微博详情Cell继承SABaseStatusCell,增加相关元素(SAStatusDetailCell)
3.1.3.5 微博详情转发Cell与评论Cell分别继承根父类,增加相关元素(SAReportCell、SACommentCell)
3.1.3.6 逻辑展示图:
3.2 数据模型、数据框架模型、Cell三者都配套使用,数据模型为数据框架模型的属性、数据框架模型为Cell的属性,分别遵循:【根父类--父类--子类】面向对象的基本继承思想,同时,数据模型将从服务器取回的数据转换成对象模型,数据框架模型再将数据模型再次转成Cell所需要的数据内容与内容尺寸位置直接供Cell使用,遵循了面向对象的基本封装思想
3.2.1 逻辑展示图:
3.3 增加展示转发详情与评论详情,点击微博详情中这两个按钮分别向服务器请求当前微博的转发详情或评论详情,重新加载表格内容,将请求到的数据展示出来
4、关键代码
代码目录:
数据模型:
SABaseText
SAStatus
SAComments
UITableViewCell:
SABaseTextCell
SABaseStatusCell
SAHomeStatusCell
SACommentCell
数据框架模型:
SABaseTextCellFrame
SABaseStatusCellFrame
SAHomeStatusCellFrame
SACommentFrame
============================================================
SABaseText.h
[Objective-C] 纯文本查看 复制代码 //
// SABaseText.h
// SianWeibo
//
// Created by yusian on 14-4-25.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 数据模型根父类
#import <Foundation/Foundation.h>
#import "SAUser.h"
@interface SABaseText : NSObject
@property (nonatomic, copy) NSString *text; // 正文
@property (nonatomic, strong) SAUser *user; // 用户
@property (nonatomic, copy) NSString *createdAt; // 创建时间
@property (nonatomic, copy) NSString *source; // 来源
- (id)initWithDict:(NSDictionary *)dict;
@end
SABaseText.m
[Objective-C] 纯文本查看 复制代码 //
// SABaseText.m
// SianWeibo
//
// Created by yusian on 14-4-25.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 数据模型根父类
#import "SABaseText.h"
@implementation SABaseText
#pragma mark - 1、初始化
- (id)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
self.text = dict[@"text"]; // 正文
self.user = [SAUser statusUserWithDict:dict[@"user"]]; // 用户
self.createdAt = dict[@"created_at"]; // 创建时间
self.source = dict[@"source"]; // 来源
}
return self;
}
#pragma mark - 2、重写set/get方法
#pragma mark 2.1、重写时间get方法格式化输出
-(NSString *)createdAt
{
// 取出数据结构为: Sat Apr 19 19:15:53 +0800 2014,将数据格式化输出业务数据
NSDateFormatter *dfm = [[NSDateFormatter alloc] init];
dfm.dateFormat = @"EEE MMM dd HH:mm:ss zzzz yyyy";
dfm.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
// 格式取出的字符串,获取时间对象
NSDate *createdTime = [dfm dateFromString:_createdAt];
dfm.dateFormat = @"M月d日 HH点mm分";
// 时间格式化成字符串
NSString *createdTimeStr = [dfm stringFromDate:createdTime];
NSTimeInterval time = [[NSDate date] timeIntervalSinceDate:createdTime];
NSTimeInterval second = time; // 时间单位换算成 秒
NSTimeInterval minute = time / 60; // 时间单位换算成 分
NSTimeInterval hour = minute / 60; // 时间单位换算成 时
NSTimeInterval day = hour / 24; // 时间单位换算成 天
NSTimeInterval year = day / 365; // 时间单位换算成 年
if (second < 60) { // 1分钟之内显示 "刚刚"
return @"刚刚";
} else if (minute < 60) { // 1小时之内显示 "x分钟前"
return [NSString stringWithFormat:@"%.f分钟前", minute];
} else if (hour < 24) { // 1天之内显示 "x小时前"
return [NSString stringWithFormat:@"%.f小时前", hour];
} else if (day < 7) { // 1周之内显示 "x天前"
return [NSString stringWithFormat:@"%.f天前", day];
} else if (year >= 1) { // 1年以前显示 "xxxx年x月x日"
dfm.dateFormat = @"yyyy年M月d日";
return [dfm stringFromDate:createdTime];
} else { // 1年以内显示 "x月x日 x点x分"
return createdTimeStr;
}
}
#pragma mark 2.2、重写来源set方法格式化存储
-(void)setSource:(NSString *)source
{
// 源source结构为: <a href="http://app.weibo.com/t/feed/4ACxed" rel="nofollow">iPad客户端</a>
NSInteger begin = [source rangeOfString:@">"].location + 1;
NSInteger end = [source rangeOfString:@"</a>"].location;
NSString *tempStr = [source substringWithRange:NSMakeRange(begin, end - begin)];
// 从字符串取出"iPad客户端"再在前面拼接"来自"
_source = [NSString stringWithFormat:@"来自%@", tempStr];
}
@end
SAStatus.h
[Objective-C] 纯文本查看 复制代码 //
// SAStatus.h
// SianWeibo
//
// Created by yusian on 14-4-16.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 微博数据模型
#import "SABaseText.h"
@interface SAStatus : SABaseText
@property (nonatomic, assign) long long ID; // 微博ID
@property (nonatomic, strong) SAStatus *retweetedStatus; // 转发体
@property (nonatomic, assign) NSInteger repostsCount; // 转发数
@property (nonatomic, assign) NSInteger commentsCount; // 评论数
@property (nonatomic, assign) NSInteger attitudesCount; // 点赞数
@property (nonatomic, strong) NSArray *picUrls; // 配图
+ (id)statusWithDict:(NSDictionary *)dict;
@end
SAStatus.m
[Objective-C] 纯文本查看 复制代码 //
// SAStatus.m
// SianWeibo
//
// Created by yusian on 14-4-16.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 微博数据模型
#import "SAStatus.h"
@implementation SAStatus
- (id)initWithDict:(NSDictionary *)dict
{
if (self = [super initWithDict:dict]) {
self.ID = [dict[@"id"] longLongValue]; // 微博ID
self.repostsCount = [dict[@"reposts_count"] intValue]; // 转发数
self.commentsCount = [dict[@"comments_count"] intValue]; // 评论数
self.attitudesCount = [dict[@"attitudes_count"] intValue]; // 点赞数
self.picUrls = dict[@"pic_urls"]; // 配图
NSDictionary *retweetedStatus = dict[@"retweeted_status"];
if (retweetedStatus) { // 转发体(被转载的微博内容)
self.retweetedStatus = [[SAStatus alloc] initWithDict:retweetedStatus];
}
}
return self;
}
+ (id)statusWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
@end
SAComments.h
[Objective-C] 纯文本查看 复制代码 //
// SAComments.h
// SianWeibo
//
// Created by yusian on 14-4-24.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SABaseText.h"
@interface SAComments : SABaseText
+ (id)commentsWithDict:(NSDictionary *)dict;
@end
SAComments.m[Objective-C] 纯文本查看 复制代码 //
// SAComments.m
// SianWeibo
//
// Created by yusian on 14-4-24.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SAComments.h"
@implementation SAComments
- (id)initWithDict:(NSDictionary *)dict
{
if (self = [super initWithDict:dict]) {
// 扩展
}
return self;
}
+ (id)commentsWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
@end
SABaseTextCell.h
[Objective-C] 纯文本查看 复制代码 //
// SABaseTextCell.h
// SianWeibo
//
// Created by yusian on 14-4-25.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Cell根父类
#import <UIKit/UIKit.h>
@class SABaseTextCellFrame;
@interface SABaseTextCell : UITableViewCell
@property (nonatomic, strong) SABaseTextCellFrame *cellFrame;
+ (NSString *)ID;
@end
SABaseTextCell.m
[Objective-C] 纯文本查看 复制代码 //
// SABaseTextCell.m
// SianWeibo
//
// Created by yusian on 14-4-25.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Cell根父类
#import "SABaseTextCell.h"
#import "SAAvata.h"
#import "SABaseTextCellFrame.h"
#import "SABaseText.h"
@interface SABaseTextCell()
{
SAAvata *_avata; // 头像
UILabel *_screenName; // 昵称
UIImageView *_mbIcon; // 会员图标
UILabel *_time; // 时间
UILabel *_source; // 来源
UILabel *_text; // 正文
}
@end
@implementation SABaseTextCell
#pragma mark - 1、初始化
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// 1、基本设置
self.backgroundColor = [UIColor clearColor];
self.backgroundView = nil;
// 2、添加子控件
[self creatSubView];
}
return self;
}
#pragma mark - 2、创建子控件
-(void)creatSubView
{
// 1、头像
_avata = [[SAAvata alloc] init];
_avata.backgroundColor = [UIColor clearColor];
[self.contentView addSubview:_avata];
// 2、昵称
_screenName = [[UILabel alloc] init];
_screenName.backgroundColor = [UIColor clearColor];
_screenName.font = kScreenNameFount;
[self.contentView addSubview:_screenName];
// 3、会员图标
_mbIcon = [[UIImageView alloc] init];
_mbIcon.image = [UIImage imageNamed:@"common_icon_membership.png"];
[self.contentView addSubview:_mbIcon];
// 4、时间
_time = [[UILabel alloc] init];
_time.backgroundColor = [UIColor clearColor];
_time.font = kTimeFont;
_time.textColor = kTimeColor;
[self.contentView addSubview:_time];
// 4、来源
_source = [[UILabel alloc] init];
_source.backgroundColor = [UIColor clearColor];
_source.font = kSourceFont;
_source.textColor = [UIColor grayColor];
[self.contentView addSubview:_source];
// 5、正文
_text = [[UILabel alloc] init];
_text.backgroundColor = [UIColor clearColor];
_text.font = kTextFount;
_text.numberOfLines = 0;
[self.contentView addSubview:_text];
}
#pragma mark - 3、设置子控件
-(void)setCellFrame:(SABaseTextCellFrame *)cellFrame
{
_cellFrame = cellFrame;
// 设置内容
[self settingSubViewForContent];
// 设置Frame
[self settingSubViewForFrame];
}
#pragma mark 3.1、设置子控件内容
- (void)settingSubViewForContent
{
// 1、设置头像
[_avata setUser:_cellFrame.dataModel.user ofType:_cellFrame.avataType];
// 2、设置昵称
_screenName.text = _cellFrame.dataModel.user.screenName;
if (_cellFrame.dataModel.user.mbtype == kMbTypeNone) {
_screenName.textColor = kScreenNameColor;
} else {
_screenName.textColor = kMBScreenNameColor;
}
// 3 设置会员图标
if (_cellFrame.dataModel.user.mbtype == kMbTypeNone) {
_mbIcon.hidden = YES;
} else {
_mbIcon.hidden = NO;
}
// 4、设置时间
_time.text = _cellFrame.dataModel.createdAt;
// 5、设置来源
_source.text = _cellFrame.dataModel.source;
// 6、设置正文
_text.text = _cellFrame.dataModel.text;
}
#pragma mark 3.2、设置子控件Frame
- (void)settingSubViewForFrame
{
// 1、设置头像尺寸位置
_avata.frame = _cellFrame.avataRect;
// 2、设置昵称尺寸位置
_screenName.frame = _cellFrame.screenNameRect;
// 3、设置会员图标尺寸位置
_mbIcon.frame = _cellFrame.mbIconRect;
// 4、设置时间尺寸位置
CGRect timeFrame = _cellFrame.timeRect;
timeFrame.size = [_cellFrame.dataModel.createdAt sizeWithFont:kTimeFont];
_time.frame = timeFrame;
// 5、设置来源尺寸位置
CGRect sourceFrame = _cellFrame.sourceRect;
sourceFrame.origin.x = CGRectGetMaxX(timeFrame) + kInterval;
_source.frame = sourceFrame;
// 6、设置正文尺寸位置
_text.frame = _cellFrame.textRect;
}
#pragma mark - 4、设置Cell标识
+(NSString *)ID
{
return @"BaseTextCell";
}
@end
SABaseStatusCell.h
[Objective-C] 纯文本查看 复制代码 //
// SABaseStatusCell.h
// SianWeibo
//
// Created by yusian on 14-4-23.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 微博类Cell父类
#import "SABaseTextCell.h"
#import "SABaseStatusCellFrame.h"
@interface SABaseStatusCell : SABaseTextCell
@property (nonatomic, strong) SABaseStatusCellFrame *cellFrame; // 框架模型
@property (nonatomic, strong) UIImageView *retweet; // 转发体视图
@end
SABaseStatusCell.m
[Objective-C] 纯文本查看 复制代码 //
// SABaseCell.m
// SianWeibo
//
// Created by yusian on 14-4-23.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 微博类Cell父类
#import "SABaseStatusCell.h"
#import "SAStatus.h"
#import "UIImage+SA.h"
#import "SAHomeStatusCellFrame.h"
#import "SAImageListView.h"
@interface SABaseStatusCell ()
{
SAImageListView *_image; // 配图
UIImageView *_retweet; // 转发体视图
UILabel *_reScreenName; // 转发体昵称
UILabel *_reText; // 转发体正文
SAImageListView *_reImage; // 转发体配图
}
@end
@implementation SABaseStatusCell
#pragma mark - 1、初始化
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
UIImage *BGView = [UIImage resizeImage:@"common_card_background.png"];
self.backgroundView = [[UIImageView alloc] initWithImage:BGView];
UIImage *selectedBGView = [UIImage resizeImage:@"common_card_background_highlighted.png"];
self.selectedBackgroundView = [[UIImageView alloc] initWithImage:selectedBGView];
[self creatBAseStatusSubView];
}
return self;
}
#pragma mark - 2、创建子控件
- (void)creatBAseStatusSubView
{
// 1、配图
_image = [[SAImageListView alloc] init];
_image.contentMode = UIViewContentModeScaleAspectFit;
[self.contentView addSubview:_image];
// 2、转发体视图
_retweet = [[UIImageView alloc] init];
NSString *imageName = @"timeline_retweet_background.png";
_retweet.image = [[UIImage imageNamed:imageName] stretchableImageWithLeftCapWidth:25 topCapHeight:10];
_retweet.userInteractionEnabled = YES;
[self.contentView addSubview:_retweet];
// 3、转发体昵称
_reScreenName = [[UILabel alloc] init];
_reScreenName.font = kReScreenNameFont;
_reScreenName.backgroundColor = [UIColor clearColor];
_reScreenName.textColor = [UIColor blueColor];
[_retweet addSubview:_reScreenName];
// 4、转发体正文
_reText = [[UILabel alloc] init];
_reText.numberOfLines = 0;
_reText.font = kReTextFont;
_reText.backgroundColor = [UIColor clearColor];
[_retweet addSubview:_reText];
// 5、转发体配图
_reImage = [[SAImageListView alloc] init];
_reImage.contentMode = UIViewContentModeScaleAspectFit;
[_retweet addSubview:_reImage];
}
#pragma mark - 3、设置子控件
-(void)setCellFrame:(SABaseStatusCellFrame *)cellFrame
{
[super setCellFrame:cellFrame];
// 1、设置子控件内容
[self settingBaseStatusSubViewContent];
// 2、计算子控件Frame
[self settingBaseStatusSubViewFrame];
}
#pragma mark 3.1、设置子控件内容
- (void)settingBaseStatusSubViewContent
{
SAStatus *status = self.cellFrame.dataModel;
// 1、设置配图
if (status.picUrls.count) { // 第一种情况:带有配图的微博
_image.hidden = NO;
_retweet.hidden = YES;
_image.imageList = status.picUrls;
} else if (status.retweetedStatus) { // 第二种情况:转发的微博
_image.hidden = YES;
_retweet.hidden = NO;
// 2、设置转发体昵称
_reScreenName.text = [NSString stringWithFormat:@"@%@", status.retweetedStatus.user.screenName];
// 3、转发体正文
_reText.text = status.retweetedStatus.text;
// 4、转发体配图
if (status.retweetedStatus.picUrls.count) { // 第二种情况:1、转发的微博带配图
_reImage.hidden = NO;
_reImage.imageList = status.retweetedStatus.picUrls;
} else { // 第二种情况:2、转发的微博不带配图
// 无配图则不显示
_reImage.hidden = YES;
}
} else { // 第三种情况:不带配图的微博
_image.hidden = YES;
_retweet.hidden = YES;
}
}
#pragma mark 3.2、设置子控件Frame
- (void)settingBaseStatusSubViewFrame
{
// 1、设置配图尺寸位置
_image.frame = self.cellFrame.image;
// 2、设置转发体尺寸位置
_retweet.frame = self.cellFrame.retweet;
// 3、设置转发体昵称尺寸位置
_reScreenName.frame = self.cellFrame.reScreenName;
// 4、转发体正文尺寸位置
_reText.frame = self.cellFrame.reText;
// 5、转发体配图尺寸位置
_reImage.frame = self.cellFrame.reImage;
}
#pragma mark - 4、重写frame方法设置Cell宽度
-(void)setFrame:(CGRect)frame
{
frame.origin.x += kCellMargins;
frame.size.width -= (2 *kCellMargins);
frame.origin.y += kCellMargins;
frame.size.height -= kCellMargins;
[super setFrame:frame];
}
#pragma mark - 5、设置Cell标识
+(NSString *)ID
{
return @"BaseStatusCell";
}
@end
SAHomeStatusCell.h
[Objective-C] 纯文本查看 复制代码 //
// SAHomeStatusCell.h
// SianWeibo
//
// Created by yusian on 14-4-18.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 微博单元格类
#import "SABaseStatusCell.h"
#import "SAHomeStatusCellFrame.h"
@interface SAHomeStatusCell : SABaseStatusCell
@end
SAHomeStatusCell.m
[Objective-C] 纯文本查看 复制代码 //
// SAHomeStatusCell.m
// SianWeibo
//
// Created by yusian on 14-4-18.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 微博单元格类
#import "SAHomeStatusCell.h"
#import "SAStatusDock.h"
@interface SAHomeStatusCell ()
{
SAStatusDock *_statusDock; // 功能菜单
}
@end
@implementation SAHomeStatusCell
#pragma mark 1、初始化Cell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// 1、添加功能菜单
_statusDock = [[SAStatusDock alloc] init];
[self.contentView addSubview:_statusDock];
}
return self;
}
#pragma mark - 2、设置Cell内容
-(void)setCellFrame:(SAHomeStatusCellFrame *)cellFrame
{
[super setCellFrame:cellFrame];
// 1、设置功能菜单栏内容
_statusDock.status = cellFrame.dataModel;
}
#pragma mark - 3、设置Cell标识
+ (NSString *)ID
{
return @"HomeStatusCell";
}
@end
SACommentCell.h
[Objective-C] 纯文本查看 复制代码 //
// SACommentCell.h
// SianWeibo
//
// Created by yusian on 14-4-26.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SABaseTextCell.h"
#import "SACommentCellFrame.h"
@interface SACommentCell : SABaseTextCell
@property (nonatomic, strong) SACommentCellFrame *cellFrame;
- (void)setGroupCellStyleWithTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
@end
SACommentCell.m
[Objective-C] 纯文本查看 复制代码 //
// SACommentCell.m
// SianWeibo
//
// Created by yusian on 14-4-26.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SACommentCell.h"
#import "UIImage+SA.h"
@interface SACommentCell()
{
UIImageView *_normalImageView;
UIImageView *_selectedImageView;
}
@end
@implementation SACommentCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
_normalImageView = [[UIImageView alloc] init];
_selectedImageView = [[UIImageView alloc] init];
self.backgroundView = _normalImageView;
self.selectedBackgroundView = _selectedImageView;
}
return self;
}
- (void)setGroupCellStyleWithTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger cellRows = [tableView numberOfRowsInSection:indexPath.section];
if (indexPath.row == cellRows - 1) {
_normalImageView.image = [UIImage resizeImage:@"statusdetail_comment_background_bottom.png"];
_selectedImageView.image = [UIImage resizeImage:@"statusdetail_comment_background_bottom_highlighted.png"];
} else {
_normalImageView.image = [UIImage resizeImage:@"statusdetail_comment_background_middle.png"];
_selectedImageView.image = [UIImage resizeImage:@"statusdetail_comment_background_middle_highlighted.png"];
}
}
-(void)setCellFrame:(SACommentCellFrame *)cellFrame
{
[super setCellFrame:cellFrame];
}
#pragma mark - 重写frame方法设置Cell宽度
-(void)setFrame:(CGRect)frame
{
frame.origin.x += kCellMargins;
frame.size.width -= (2 *kCellMargins);
[super setFrame:frame];
}
@end
SABaseTextCellFrame.h
[Objective-C] 纯文本查看 复制代码 //
// SABaseTextCellFrame.h
// SianWeibo
//
// Created by yusian on 14-4-25.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Cell根父类框架模型
#import <Foundation/Foundation.h>
#import "SAAvata.h"
@class SABaseText;
@interface SABaseTextCellFrame : NSObject
@property (nonatomic, readonly) CGRect avataRect; // 头像
@property (nonatomic, readonly) CGRect screenNameRect; // 昵称
@property (nonatomic, readonly) CGRect mbIconRect; // 会员图标
@property (nonatomic, assign) CGRect timeRect; // 时间
@property (nonatomic, assign) CGRect sourceRect; // 来源
@property (nonatomic, assign) CGRect textRect; // 正文
@property (nonatomic, assign) CGFloat cellHeight; // 行高
@property (nonatomic, readonly) CGFloat cellWidth; // 行宽
@property (nonatomic, assign) SAAvataType avataType; // 头像类型
@property (nonatomic, strong) SABaseText *dataModel; // 数据模型
-(void)setDataModel:(SABaseText *)dataModel withAvataType:(SAAvataType)avataType;
@end
SABaseTextCellFrame.m
[Objective-C] 纯文本查看 复制代码 //
// SABaseTextCellFrame.m
// SianWeibo
//
// Created by yusian on 14-4-25.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Cell根父类框架模型
#import "SABaseTextCellFrame.h"
#import "SABaseText.h"
@implementation SABaseTextCellFrame
#pragma mark - 设置数据模型计算框架模型(头像大小默认为small)
-(void)setDataModel:(SABaseText *)dataModel
{
_dataModel = dataModel;
CGSize screenSize = [UIScreen mainScreen].applicationFrame.size;
_cellWidth = screenSize.width - 2 * kCellMargins;
// 1、设置头像尺寸位置;
CGFloat avataX = kInterval;
CGFloat avataY = kInterval;
_avataRect = (CGRect){{avataX, avataY}, [SAAvata sizeOfAvataType:_avataType]};
// 2、设置昵称尺寸位置;
CGFloat screenNameX = CGRectGetMaxX(_avataRect) + kInterval;
CGFloat screenNameY = avataY;
CGSize screenNameSize = [dataModel.user.screenName sizeWithFont:kScreenNameFount];
_screenNameRect = (CGRect){{screenNameX, screenNameY}, screenNameSize};
// 3、设置会员图标尺寸位置
CGFloat mbIconX = CGRectGetMaxX(_screenNameRect) + kInterval;
CGFloat mbIconY = (screenNameSize.height - kMBIconWH) * 0.5 + screenNameY;
_mbIconRect = CGRectMake(mbIconX, mbIconY, kMBIconWH, kMBIconWH);
// 4、默认高度
_cellHeight = MAX(CGRectGetHeight(_avataRect), CGRectGetHeight(_screenNameRect)) + kInterval;
}
#pragma mark - 根据头像大小设置数据模型计算框架模型
-(void)setDataModel:(SABaseText *)dataModel withAvataType:(SAAvataType)avataType
{
_avataType = avataType;
[self setDataModel:dataModel];
}
@end
SABaseStatusCellFrame.h
[Objective-C] 纯文本查看 复制代码 //
// SABaseStatusCellFrame.h
// SianWeibo
//
// Created by yusian on 14-4-23.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SABaseTextCellFrame.h"
#import "SAStatus.h"
@interface SABaseStatusCellFrame : SABaseTextCellFrame
{
CGRect _retweet; // 转发体Frame
}
@property (nonatomic, readonly) CGRect image; // 配图
@property (nonatomic, readonly) CGRect retweet; // 转发体视图
@property (nonatomic, readonly) CGRect reScreenName; // 转发体昵称
@property (nonatomic, readonly) CGRect reText; // 转发体正文
@property (nonatomic, readonly) CGRect reImage; // 转发体配图
@property (nonatomic, strong) SAStatus *dataModel; // 数据模型
@end
SABaseStatusCellFrame.m
[Objective-C] 纯文本查看 复制代码 //
// SABaseStatusCellFrame.m
// SianWeibo
//
// Created by yusian on 14-4-23.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SABaseStatusCellFrame.h"
#import "SAAvata.h"
#import "SAImageListView.h"
@implementation SABaseStatusCellFrame
-(void)setDataModel:(SAStatus *)dataModel
{
[super setDataModel:dataModel];
// 1、设置时间尺寸位置
CGFloat timeX = self.screenNameRect.origin.x;
CGFloat timeY = CGRectGetMaxY(self.screenNameRect) + kInterval * 0.5;
CGSize timeSize = [dataModel.createdAt sizeWithFont:kTimeFont];
self.timeRect = (CGRect){{timeX, timeY}, timeSize};
// 2、设置来源尺寸位置
CGFloat sourceX = CGRectGetMaxX(self.timeRect) + kInterval;
CGFloat sourceY = timeY;
CGSize sourceSize = [dataModel.source sizeWithFont:kSourceFont];
self.sourceRect = (CGRect){{sourceX, sourceY}, sourceSize};
// 3、设置正文尺寸位置;
CGFloat textX = self.avataRect.origin.x;
CGFloat textY = MAX (CGRectGetMaxY(self.avataRect), CGRectGetMaxY(self.timeRect));
CGFloat textW = self.cellWidth - 2 * kInterval;
CGSize textSize = [dataModel.text sizeWithFont:kTextFount constrainedToSize:CGSizeMake(textW, MAXFLOAT)];
self.textRect = (CGRect){{textX, textY}, textSize};
if (dataModel.picUrls.count) { // 第一种情况:带配图的微博
// 4、设置配图尺寸位置
CGFloat imageX = kInterval;
CGFloat imageY = CGRectGetMaxY(super.textRect) + kInterval;
CGSize imageSize = [SAImageListView sizeOfViewWithImageCount:dataModel.picUrls.count];
_image = (CGRect){{imageX, imageY}, imageSize};
// 有配图无转发体单元格高度
self.cellHeight = CGRectGetMaxY(_image) + kInterval + kCellMargins;
} else if (dataModel.retweetedStatus) { // 第二种情况:转发的微博
// 5、设置转发体尺寸位置
CGFloat retweetX = kInterval;
CGFloat retweetY = CGRectGetMaxY(self.textRect) + kInterval;
CGFloat retweetW = self.cellWidth - 2 * kInterval;
// 6、设置转发体昵称尺寸位置
CGFloat reScreenNameX = kInterval;
CGFloat reScreenNameY = kInterval;
CGSize reScreenNameSize = [[NSString stringWithFormat:@"@%@", dataModel.retweetedStatus.user.screenName] sizeWithFont:kReScreenNameFont];
_reScreenName = (CGRect){{reScreenNameX, reScreenNameY}, reScreenNameSize};
// 7、设置转发体正文尺寸位置
CGFloat reTextX = reScreenNameX;
CGFloat reTextY = CGRectGetMaxY(_reScreenName) + kInterval;
CGSize reTextSize = [dataModel.retweetedStatus.text sizeWithFont:kReTextFont constrainedToSize:CGSizeMake((retweetW - 2 * kInterval), MAXFLOAT)];
_reText = (CGRect){{reTextX, reTextY}, reTextSize};
// 8、设置转发体配图尺寸位置
if (dataModel.retweetedStatus.picUrls.count) { // 第二种情况:1、转发的微博带图
CGFloat reImageX = reScreenNameX;
CGFloat reImageY = CGRectGetMaxY(_reText) + kInterval;
CGSize reImageSize = [SAImageListView sizeOfViewWithImageCount:dataModel.retweetedStatus.picUrls.count];
_reImage = (CGRect){{reImageX, reImageY}, reImageSize};
// 转发体有配图转发体尺寸
CGFloat retweetH = CGRectGetMaxY(_reImage) + kInterval;
_retweet = CGRectMake(retweetX, retweetY, retweetW, retweetH);
} else { // 第二种情况:2、转发的微博不带图
// 转发体无配图转发体尺寸
CGFloat retweetH = CGRectGetMaxY(_reText) + kInterval;
_retweet = CGRectMake(retweetX, retweetY, retweetW, retweetH);
}
// 有转发体的单元格高度
self.cellHeight = CGRectGetMaxY(_retweet) + kInterval + kCellMargins;
} else { // 第三种情况:不带配图的普通微博
// 9、设置单元格高度尺寸位置
// 无配图,无转发体单元格高度
self.cellHeight = CGRectGetMaxY(super.textRect) + kInterval + kCellMargins;
}
}
@end
SAHomeStatusCellFrame.h
[Objective-C] 纯文本查看 复制代码 //
// SAHomeStatusCellFrame.h
// SianWeibo
//
// Created by yusian on 14-4-18.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 数据框架模型
#import "SABaseStatusCellFrame.h"
@interface SAHomeStatusCellFrame : SABaseStatusCellFrame
@end
SAHomeStatusCellFrame.m
[Objective-C] 纯文本查看 复制代码 //
// SAHomeStatusCellFrame.m
// SianWeibo
//
// Created by yusian on 14-4-18.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 数据框架模型
#import "SAHomeStatusCellFrame.h"
@implementation SAHomeStatusCellFrame
-(void)setDataModel:(SAStatus *)dataModel
{
[super setDataModel:dataModel];
self.cellHeight += kStatusDockHeight;
}
@end
SACommentFrame.h
[Objective-C] 纯文本查看 复制代码 //
// SACommentCellFrame.h
// SianWeibo
//
// Created by yusian on 14-4-26.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SABaseTextCellFrame.h"
#import "SAComments.h"
@interface SACommentCellFrame : SABaseTextCellFrame
@property (nonatomic, strong) SAComments *dataModel;
@end
SACommentFrame.m
[Objective-C] 纯文本查看 复制代码 //
// SACommentCellFrame.m
// SianWeibo
//
// Created by yusian on 14-4-26.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SACommentCellFrame.h"
@implementation SACommentCellFrame
-(void)setDataModel:(SAComments *)dataModel
{
[super setDataModel:dataModel];
// 1、正文
CGFloat textX = self.screenNameRect.origin.x;
CGFloat textY = CGRectGetMaxY(self.screenNameRect);
CGFloat textWidth = self.cellWidth - self.avataRect.size.width - 3 * kInterval;
CGSize textSize = [dataModel.text sizeWithFont:kTextFount constrainedToSize:CGSizeMake(textWidth, MAXFLOAT)];
self.textRect = (CGRect){{textX, textY}, textSize};
// 2、时间
CGFloat timeX = textX;
CGFloat timeY = CGRectGetMaxY(self.textRect) + kInterval;
CGSize timeSize = [dataModel.createdAt sizeWithFont:kTimeFont];
self.timeRect = (CGRect){{timeX, timeY}, timeSize};
self.cellHeight = CGRectGetMaxY(self.timeRect) + kCellMargins + kInterval;
}
@end
5、源码下载
相关主题链接
1、ios实战开发之仿新浪微博(第一讲:新特性展示)
2、ios实战开发之仿新浪微博(第二讲:主框架搭建)
3、ios实战开发之仿新浪微博(第三讲:更多界面搭建)
4、ios实战开发之仿新浪微博(第四讲:OAuth认证)
5、ios实战开发之仿新浪微博(第五讲:微博数据加载)
6、ios实战开发之仿新浪微博(第六讲:微博数据展示一)
7、ios实战开发之仿新浪微博(第七讲:微博数据展示二)
8、ios实战开发之仿新浪微博(第八讲:微博数据展示三)
9、ios实战开发之仿新浪微博(第九讲:微博功能完善一)
10、ios实战开发之仿新浪微博(第十讲:微博功能完善二)
11、ios实战开发之仿新浪微博(第十一讲:微博功能完善三)
12、ios实战开发之仿新浪微博(小龙虾发布版)
|