年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 17117|回复: 40

[新浪微博] ios实战开发之仿新浪微博(第十一讲:微博功能完善三)

[复制链接]
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

    发表于 2014-4-27 00:16:45 | 显示全部楼层 |阅读模式
    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 逻辑展示图:

    dataModel.png

    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 逻辑展示图:

    cellFrame.png

    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 逻辑展示图:

    cell.png

    3.2 数据模型、数据框架模型、Cell三者都配套使用,数据模型为数据框架模型的属性、数据框架模型为Cell的属性,分别遵循:【根父类--父类--子类】面向对象的基本继承思想,同时,数据模型将从服务器取回的数据转换成对象模型,数据框架模型再将数据模型再次转成Cell所需要的数据内容与内容尺寸位置直接供Cell使用,遵循了面向对象的基本封装思想
    3.2.1 逻辑展示图:

    foundation.png

    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实战开发之仿新浪微博(小龙虾发布版)

    该用户从未签到

    发表于 2014-6-6 17:06:34 | 显示全部楼层
    顶顶顶,好贴,全部顶
    :lol

    该用户从未签到

    发表于 2014-10-11 15:13:32 | 显示全部楼层
    :):)谢谢分享
    回复

    使用道具 举报

  • TA的每日心情
    倒霉
    2014-11-11 21:18
  • 签到天数: 18 天

    [LV.4]偶尔看看III

    发表于 2014-10-19 00:23:59 | 显示全部楼层
    跟好好久,明天可以到这里了

    该用户从未签到

    发表于 2014-11-11 21:21:40 | 显示全部楼层
    谢谢分享,学习了!
  • TA的每日心情
    发光
    2014-11-26 14:19
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2014-12-9 12:54:21 | 显示全部楼层
    遇到bug了还没解决

    该用户从未签到

    发表于 2014-12-9 22:21:03 | 显示全部楼层
    xiexiedashen
  • TA的每日心情
    奋斗
    2014-12-11 13:21
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2014-12-11 15:32:12 | 显示全部楼层
    学习一下,谢谢分享
  • TA的每日心情
    得瑟
    2015-1-8 17:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-12-20 17:43:15 | 显示全部楼层
    准备练习下学的知识,借来练练手

    该用户从未签到

    发表于 2015-1-3 21:35:05 | 显示全部楼层
    谢谢谢谢谢谢谢谢谢谢谢谢谢谢楼主
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|小黑屋|Archiver|iOS开发笔记 ( 湘ICP备14010846号 )

    GMT+8, 2024-3-28 21:18 , Processed in 0.056506 second(s), 26 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表