年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 12892|回复: 32

[新浪微博] ios实战开发之仿新浪微博(第七讲:微博数据展示二)

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

    [LV.9]以坛为家II

    发表于 2014-4-20 12:40:02 | 显示全部楼层 |阅读模式
    1、效果展示

    iOS 模拟器屏幕快照“2014年4月20日 上午9.57.19”.png iOS 模拟器屏幕快照“2014年4月20日 上午9.57.39”.png iOS 模拟器屏幕快照“2014年4月20日 下午12.01.15”.png

    2、主要内容

    2.1 优化用户头像显示,增加用户类型标志
    2.2 增加会员图标显示功能
    2.3 增加会员名称橙色显示功能
    2.4 修复微博发表时间显示不正常的问题
    2.5 修复来源无法显示的问题
    2.6 增加被转发微博显示背景
    2.7 优化图片展示方式

    3、设计说明
    3.1 用户头像与用户类型在应用中多处需要使用,并且这两者有直接关系,因此将用户头像及附属属性单独创建一个类进行管理;
    3.2 添加一个控件用来显示尊贵会员图标,通过用户属性值来判断其隐藏或显示;
    3.3 会员昵称显示颜色同样通过用户属性来判断;
    3.4 微博发表时间与来源在微博数据中都为未加工的原始数据,通过在模型的set或get方法中对其加工成应用所需要的数据;
    3.5 美化微博转发体的背景显示效果
    3.6 微博配图有一张或多张情况,一张图以大图展示,多张图以九宫格形式展示,单独创建一个类来处理该数据

    4、关键代码
    SACommon.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SACommon.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-10.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  公共头文件
    
    #ifndef __SACOMMON_H__
    #define __SACOMMON_H__
    // 判断是否为iphone5的宏
    #define isIPhone5 ([UIScreen mainScreen].bounds.size.height == 568)
    
    // 用MyLog替代NSLog,调试时输出日志,正式发布时自动取消日志输出代码
    #ifdef DEBUG
    #define MyLog(...) NSLog(__VA_ARGS__)
    #else
    #define MyLog(...)
    #endif
    
    // SAOAuthController:OAuth认证
    #define kOAuthURL [kBaseURL stringByAppendingString:@"oauth2/authorize"]    // 新浪OAuth认证URL
    #define kAppKey @"660705995"                                                // 开发者帐号AppKey
    #define kAppSecret @"38d9d1d644844050dbb2703cb6bc6db6"                      // 开发者帐号AppSecret
    #define kClient_id @"660705995"                                             // 新浪OAuth认证ClientID
    #define kRedirect_uri @"http://www.yusian.com"                              // 新浪OAuth认证回调页面
    #define kBaseURL @"https://api.weibo.com/"                                  // 新浪OAuth认证域名
    
    // SAStatusFrame:微博Frame设置
    #define kInterval           10                                              // 微博元素基本边距
    #define kProfileWH          34                                              // 用户头像尺寸
    #define kScreenNameFount    [UIFont systemFontOfSize:15]                    // 用户昵称字号
    #define kMBIconWH           12                                              // 会员图标尺寸
    #define kTimeFont           [UIFont systemFontOfSize:10]                    // 发表时间字号
    #define kSourceFont         kTimeFont                                       // 微博来源字号
    #define kTextFount          [UIFont systemFontOfSize:15]                    // 微博正文字号
    #define kReScreenNameFont   [UIFont systemFontOfSize:14]                    // 转发微博体昵称字号
    #define kReTextFont         kReScreenNameFont                               // 转发微博体正文字号
    
    // SAAvata:微博头像处理
    #define kAvataSmallW    34                                                  // 用户小头像尺寸宽度
    #define kAvataSmallH    kAvataSmallW                                        // 用户小头像尺寸高度
    #define kAvataDefaultW  50                                                  // 用户中头像尺寸宽度
    #define kAvataDefaultH  kAvataDefaultW                                      // 用户中头像尺寸高度
    #define kAvataBigW      85                                                  // 用户大头像尺寸宽度
    #define kAvataBigH      kAvataBigW                                          // 用户大头像尺寸高度
    #define kVerifiedW      18                                                  // 用户类型图标尺寸宽度
    #define kVerifiedH      kVerifiedW                                          // 用户类型图标尺寸高度
    
    // SAStatusCell:会员昵称颜色设置
    #define kColor(r, g, b)     [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
    #define kMBScreenNameColor  kColor(240, 100, 20)                            // 会员用户昵称颜色
    #define kScreenNameColor    kColor(0, 0, 0)                                 // 普通用户昵称颜色
    #define kTimeColor          kColor(200, 100, 30)                            // 微博发表时间显示颜色
    
    // SAImageListView 配图处理相关
    #define kImageCount             9                                           // 微博配图最大配图数
    #define kImageInterval          5                                           // 微博配图间隔
    #define kStatusImageOneWH       100                                         // 一张配图尺寸
    #define kStatusImageMultipleWH  80                                          // 多總配图尺寸
    
    
    #endif  // __SACOMMON_H__

    SAStatus.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAStatus.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-16.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  微博数据模型
    
    #import <Foundation/Foundation.h>
    #import "SAStatusUser.h"
    
    @interface SAStatus : NSObject
    
    @property (nonatomic, copy)     NSString        *text;              // 正文
    @property (nonatomic, strong)   SAStatusUser    *user;              // 用户
    @property (nonatomic, copy)     NSString        *createdAt;         // 创建时间
    @property (nonatomic, copy)     NSString        *source;            // 来源
    @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)initWithDict:(NSDictionary *)dict;
    
    + (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 init]) {
            self.text = dict[@"text"];                                      // 正文
            self.user = [SAStatusUser statusUserWithDict:dict[@"user"]];    // 用户
            self.createdAt = dict[@"created_at"];                           // 创建时间
            self.source = dict[@"source"];                                  // 来源
            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];
    }
    
    -(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;
        }
    }
    
    
    -(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
    

    SAStatusUser.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAStatusUser.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-16.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    typedef enum {
        kVerifiedTypeNone           = -1,   // 无认证
        kVerifiedTypePersonal       = 0,    // 个人认证
        kVerifiedTypeOrgEnterprice  = 2,    // 企业认证
        kVerifiedTypeOrgMedia       = 3,    // 媒体认证
        kVerifiedTypeOrgWebsite     = 5,    // 网站认证
        kVerifiedTypeDaren          = 220   // 微博达人
    }VerifiedType;
    
    typedef enum {
        kMbTypeNone,                        // 非会员
        kMbTypeNormal,                      // 普通会员
        kMbTypeYear                         // 年费会员
    }MbType;
    
    @interface SAStatusUser : NSObject
    
    @property (nonatomic, copy)     NSString        *screenName;        // 昵称
    @property (nonatomic, copy)     NSString        *profileImageUrl;   // 头像
    @property (nonatomic, assign)   BOOL            verified;           // 是否验证
    @property (nonatomic, assign)   VerifiedType    verifiedType;       // 验证类型
    @property (nonatomic, assign)   NSInteger       mbrank;             // 会员等级
    @property (nonatomic, assign)   MbType          mbtype;             // 会员类型
    
    - (id)initWithDict:(NSDictionary *)dict;
    
    + (id)statusUserWithDict:(NSDictionary *)dict;
    
    @end
    

    SAStatusUser.m
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAStatusUser.m
    //  SianWeibo
    //
    //  Created by yusian on 14-4-16.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //
    
    #import "SAStatusUser.h"
    
    @implementation SAStatusUser
    
    - (id)initWithDict:(NSDictionary *)dict
    {
        if (self = [super init]) {
            self.screenName = dict[@"screen_name"];                     // 昵称
            self.profileImageUrl = dict[@"profile_image_url"];          // 头像
            self.verified = [dict[@"verified"] boolValue];              // 是否验证
            self.verifiedType = [dict[@"verified_type"] integerValue];  // 验证类型
            self.mbrank = [dict[@"mbrank"] integerValue];               // 会员等级
            self.mbtype = [dict[@"mbtype"] integerValue];               // 会员类型
        }
        return self;
    }
    
    + (id)statusUserWithDict:(NSDictionary *)dict
    {
        return [[self alloc] initWithDict:dict];
    }
    
    @end
    

    SAStatusFrame.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAStatusFrame.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-18.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "SAStatus.h"
    
    @interface SAStatusFrame : NSObject
    
    @property (nonatomic, readonly) CGRect      profile;        // 头像
    @property (nonatomic, readonly) CGRect      screenName;     // 昵称
    @property (nonatomic, readonly) CGRect      mbIcon;         // 会员图标
    @property (nonatomic, readonly) CGRect      time;           // 时间
    @property (nonatomic, readonly) CGRect      source;         // 来源
    @property (nonatomic, readonly) CGRect      text;           // 正文
    @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, readonly) CGFloat     cellHeight;     // 行高
    @property (nonatomic, strong)   SAStatus    *status;        // 数据模型
    
    @end
    

    SAStatusFrame.m
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAStatusFrame.m
    //  SianWeibo
    //
    //  Created by yusian on 14-4-18.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  数据框架模型
    
    #import "SAStatusFrame.h"
    #import "SAAvata.h"
    #import "SAImageListView.h"
    
    @implementation SAStatusFrame
    
    -(void)setStatus:(SAStatus *)status
    {
        _status = status;
        CGSize screenSize = [UIScreen mainScreen].applicationFrame.size;
        
        // 1、设置头像尺寸位置;
        CGFloat profileX = kInterval;
        CGFloat profileY = kInterval;
        _profile = (CGRect){{kInterval, kInterval}, [SAAvata sizeOfAvataType:kAvataTypeSmall]};
        
        // 2、设置昵称尺寸位置;
        CGFloat screenNameX = CGRectGetMaxX(_profile) + kInterval;
        CGFloat screenNameY = profileY;
        CGSize screenNameSize = [status.user.screenName sizeWithFont:kScreenNameFount];
        _screenName = (CGRect){{screenNameX, screenNameY}, screenNameSize};
        
        // 2.1 设置会员图标尺寸位置
        CGFloat mbIconX = CGRectGetMaxX(_screenName) + kInterval;
        CGFloat mbIconY = (screenNameSize.height - kMBIconWH) * 0.5 + screenNameY;
        _mbIcon = CGRectMake(mbIconX, mbIconY, kMBIconWH, kMBIconWH);
        
        // 3、设置时间尺寸位置
        CGFloat timeX = screenNameX;
        CGFloat timeY = CGRectGetMaxY(_screenName) + kInterval * 0.5;
        CGSize timeSize = [status.createdAt sizeWithFont:kTimeFont];
        _time = (CGRect){{timeX, timeY}, timeSize};
        
        // 4、设置来源尺寸位置
        CGFloat sourceX = CGRectGetMaxX(_time) + kInterval;
        CGFloat sourceY = timeY;
        CGSize sourceSize = [status.source sizeWithFont:kSourceFont];
        _source = (CGRect){{sourceX, sourceY}, sourceSize};
        
        // 5、设置正文尺寸位置;
        CGFloat textX = profileX;
        CGFloat textY = MAX (CGRectGetMaxY(_profile), CGRectGetMaxY(_time));
        CGFloat textW = screenSize.width - 2 * kInterval;
        CGSize textSize = [_status.text sizeWithFont:kTextFount constrainedToSize:CGSizeMake(textW, MAXFLOAT)];
        _text = (CGRect){{textX, textY}, textSize};
        
        if (_status.picUrls.count) {                            // 第一种情况:带配图的微博
            
            // 6、设置配图尺寸位置
            CGFloat imageX = profileX;
            CGFloat imageY = CGRectGetMaxY(_text) + kInterval;
            CGSize imageSize = [SAImageListView sizeOfViewWithImageCount:_status.picUrls.count];
            _image = (CGRect){{imageX, imageY}, imageSize};
            
            // 有配图无转发体单元格高度
            _cellHeight = CGRectGetMaxY(_image) + kInterval;
            
        } else if (_status.retweetedStatus) {                   // 第二种情况:转发的微博
            
            // 7、设置转发体尺寸位置
            CGFloat retweetX = profileX;
            CGFloat retweetY = CGRectGetMaxY(_text) + kInterval;
            CGFloat retweetW = screenSize.width - 2 * kInterval;
            CGFloat retweetH = kInterval;
            _retweet = CGRectMake(retweetX, retweetY, retweetW, retweetH);
            
            // 8、设置转发体昵称尺寸位置
            CGFloat reScreenNameX = kInterval;
            CGFloat reScreenNameY = kInterval;
            CGSize reScreenNameSize = [[NSString stringWithFormat:@"@%@", _status.retweetedStatus.user.screenName] sizeWithFont:kReScreenNameFont];
            _reScreenName = (CGRect){{reScreenNameX, reScreenNameY}, reScreenNameSize};
            
            // 9、设置转发体正文尺寸位置
            CGFloat reTextX = reScreenNameX;
            CGFloat reTextY = CGRectGetMaxY(_reScreenName) + kInterval;
            CGSize reTextSize = [_status.retweetedStatus.text sizeWithFont:kReTextFont constrainedToSize:CGSizeMake((screenSize.width - 4 * kInterval), MAXFLOAT)];
            _reText = (CGRect){{reTextX, reTextY}, reTextSize};
            
            // 10、设置转发体配图尺寸位置
            if (_status.retweetedStatus.picUrls.count) {              // 第二种情况:1、转发的微博带图
                CGFloat reImageX = reScreenNameX;
                CGFloat reImageY = CGRectGetMaxY(_reText) + kInterval;
                CGSize reImageSize = [SAImageListView sizeOfViewWithImageCount:_status.retweetedStatus.picUrls.count];
                _reImage = (CGRect){{reImageX, reImageY}, reImageSize};
                
                // 转发体有配图转发体尺寸
                retweetH = CGRectGetMaxY(_reImage) + kInterval;
                _retweet = CGRectMake(retweetX, retweetY, retweetW, retweetH);
                
            } else {                                            // 第二种情况:2、转发的微博不带图
                
                // 转发体无配图转发体尺寸
                retweetH = CGRectGetMaxY(_reText) + kInterval;
                _retweet = CGRectMake(retweetX, retweetY, retweetW, retweetH);
            }
            
            // 有转发体的单元格高度
            _cellHeight = CGRectGetMaxY(_retweet) + kInterval;
            
        } else {                                                // 第三种情况:不带配图的普通微博
            
            // 11、设置单元格高度尺寸位置
            // 无配图,无转发体单元格高度
            _cellHeight = CGRectGetMaxY(_text) + kInterval;
        }
    }
    
    @end
    

    SAStatusCell.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAStatusCell.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-18.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  微博单元格类
    
    #import <UIKit/UIKit.h>
    #import "SAStatusFrame.h"
    
    @interface SAStatusCell : UITableViewCell
    
    @property (nonatomic, strong) SAStatusFrame *statusFrame;
    
    + (NSString *)ID;
    
    @end
    

    SAStatusCell.m
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAStatusCell.m
    //  SianWeibo
    //
    //  Created by yusian on 14-4-18.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  微博单元格类
    
    #import "SAStatusCell.h"
    #import "UIImageView+WebCache.h"
    #import "SAAvata.h"
    #import "SAImageListView.h"
    
    @interface SAStatusCell ()
    {
        SAAvata         *_profile;      // 头像
        UILabel         *_screenName;   // 昵称
        UIImageView     *_mbIcon;       // 会员图标
        UILabel         *_time;         // 时间
        UILabel         *_source;       // 来源
        UILabel         *_text;         // 正文
        SAImageListView *_image;        // 配图
        UIImageView     *_retweet;      // 转发体视图
        UILabel         *_reScreenName; // 转发体昵称
        UILabel         *_reText;       // 转发体正文
        SAImageListView *_reImage;      // 转发体配图
    }
    @end
    
    @implementation SAStatusCell
    
    #pragma mrak 初始化单元格元素
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            
            // 1、头像
            _profile = [[SAAvata alloc] init];
            [self.contentView addSubview:_profile];
            
            // 2、昵称
            _screenName = [[UILabel alloc] init];
            _screenName.font = kScreenNameFount;
            [self.contentView addSubview:_screenName];
            
            // 2.1 会员图标
            _mbIcon = [[UIImageView alloc] init];
            _mbIcon.image = [UIImage imageNamed:@"common_icon_membership.png"];
            [self.contentView addSubview:_mbIcon];
            
            // 3、时间
            _time = [[UILabel alloc] init];
            _time.font = kTimeFont;
            _time.textColor = kTimeColor;
            [self.contentView addSubview:_time];
            
            // 4、来源
            _source = [[UILabel alloc] init];
            _source.font = kSourceFont;
            _source.textColor = [UIColor grayColor];
            [self.contentView addSubview:_source];
            
            // 5、正文
            _text = [[UILabel alloc] init];
            _text.font = kTextFount;
            _text.numberOfLines = 0;
            [self.contentView addSubview:_text];
            
            // 6、配图
            _image = [[SAImageListView alloc] init];
            _image.contentMode = UIViewContentModeScaleAspectFit;
            [self.contentView addSubview:_image];
            
            // 7、转发体视图
            _retweet = [[UIImageView alloc] init];
            _retweet.image = [[UIImage imageNamed:@"timeline_retweet_background.png"] stretchableImageWithLeftCapWidth:25 topCapHeight:10];
            [self.contentView addSubview:_retweet];
            
            // 8、转发体昵称
            _reScreenName = [[UILabel alloc] init];
            _reScreenName.font = kReScreenNameFont;
            _reScreenName.backgroundColor = [UIColor clearColor];
            _reScreenName.textColor = [UIColor blueColor];
            [_retweet addSubview:_reScreenName];
            
            // 9、转发体正文
            _reText = [[UILabel alloc] init];
            _reText.numberOfLines = 0;
            _reText.font = kReTextFont;
            _reText.backgroundColor = [UIColor clearColor];
            [_retweet addSubview:_reText];
            
            // 10、转发体配图
            _reImage = [[SAImageListView alloc] init];
            _reImage.contentMode = UIViewContentModeScaleAspectFit;
            [_retweet addSubview:_reImage];
            
        }
        return self;
    }
    
    #pragma mark - 设置单元格
    -(void)setStatusFrame:(SAStatusFrame *)statusFrame
    {
        _statusFrame = statusFrame;
        
        // 1、添加子控件
        [self statusFrameSettingView];
        
        // 2、计算子控件Frame
        [self statusFrameSettingFrame];
    }
    
    #pragma mark 设置单元格内容
    - (void)statusFrameSettingView
    {
        SAStatus *status = self.statusFrame.status;
        
        // 1、设置头像
        [_profile setUser:status.user ofType:kAvataTypeSmall];
        
        // 2、设置昵称
        _screenName.text = status.user.screenName;
        if (status.user.mbtype == kMbTypeNone) {
            _screenName.textColor = kScreenNameColor;
        } else {
            _screenName.textColor = kMBScreenNameColor;
        }
        
        // 2.1 设置会员图标
        if (status.user.mbtype == kMbTypeNone) {
            _mbIcon.hidden = YES;
        } else {
            _mbIcon.hidden = NO;
        }
        
        // 3、设置时间
        _time.text = status.createdAt;
        
        // 4、设置来源
        _source.text = status.source;
        
        // 5、设置正文
        _text.text = status.text;
        
        // 6、设置配图
        if (status.picUrls.count) {                     // 第一种情况:带有配图的微博
            
            _image.hidden = NO;
            _retweet.hidden = YES;
            
            _image.imageList = status.picUrls;
            
        } else if (status.retweetedStatus) {            // 第二种情况:转发的微博
            
            _image.hidden = YES;
            _retweet.hidden = NO;
            
            // 7、设置转发体昵称
            _reScreenName.text = [NSString stringWithFormat:@"@%@", status.retweetedStatus.user.screenName];
            
            // 8、转发体正文
            _reText.text = status.retweetedStatus.text;
            
            // 9、转发体配图
            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 单元格元素布局
    - (void)statusFrameSettingFrame
    {
        // 1、设置头像尺寸位置
        _profile.frame = _statusFrame.profile;
        
        // 2、设置昵称尺寸位置
        _screenName.frame = _statusFrame.screenName;
        
        // 2.1 设置会员图标尺寸位置
        _mbIcon.frame = _statusFrame.mbIcon;
        
        // 3、设置时间尺寸位置
        CGRect timeDynamicFrame =  _statusFrame.time;
        timeDynamicFrame.size = [_statusFrame.status.createdAt sizeWithFont:kTimeFont]; // 时间动态显示,时间尺寸动态计算
        _time.frame = timeDynamicFrame;
        
        // 4、设置来源尺寸位置
        CGRect sourceDynamicFrame = _statusFrame.source;
        sourceDynamicFrame.origin.x = CGRectGetMaxX(timeDynamicFrame) + kInterval;      // 时间尺寸动态计算,来源位置动态计算
        _source.frame = sourceDynamicFrame;
        
        // 5、设置正文尺寸位置
        _text.frame = _statusFrame.text;
        
        // 6、设置配图尺寸位置
        _image.frame = _statusFrame.image;
        
        // 7、设置转发体尺寸位置
        _retweet.frame = _statusFrame.retweet;
        
        // 8、设置转发体昵称尺寸位置
        _reScreenName.frame = _statusFrame.reScreenName;
        
        // 9、转发体正文尺寸位置
        _reText.frame = _statusFrame.reText;
        
        // 10、转发体配图尺寸位置
        _reImage.frame = _statusFrame.reImage;
    
    }
    
    #pragma mark 设置单元格标识
    + (NSString *)ID
    {
        return @"StatusCell";
    }
    
    @end
    

    SAAvata.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAAvata.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-19.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  用户头像处理类
    
    #import <UIKit/UIKit.h>
    #import "SAStatusUser.h"
    
    typedef enum {
        
        kAvataTypeSmall,    // 小图标:36 * 36
        kAvataTypeDefault,  // 中图标:50 * 50
        kAvataTypeBig       // 大图标:85 * 85
        
    } SAAvataType;
    
    @interface SAAvata : UIView
    
    @property (nonatomic, assign) SAAvataType   type;
    @property (nonatomic, strong) SAStatusUser  *user;
    
    + (CGSize)sizeOfAvataType:(SAAvataType)avataType;
    - (void)setUser:(SAStatusUser *)user ofType:(SAAvataType)type;
    - (UIImage *)placeImageWithAvataType:(SAAvataType)avataType;
    
    @end
    

    SAAvata.m
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAAvata.m
    //  SianWeibo
    //
    //  Created by yusian on 14-4-19.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  用户头像处理类
    
    #import "SAAvata.h"
    #import "UIImageView+WebCache.h"
    
    @interface SAAvata ()
    {
        UIImageView *_icon;
        UIImageView *_verified;
    }
    @end
    @implementation SAAvata
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            
            // 1、设置头像
            _icon = [[UIImageView alloc] init];
            [self addSubview:_icon];
            
            // 2、设置认证图标
            _verified = [[UIImageView alloc] init];
            [self addSubview:_verified];
            
        }
        return self;
    }
    
    #pragma mark 返回不同类型头像的尺寸
    + (CGSize)sizeOfAvataType:(SAAvataType)avataType
    {
        switch (avataType) {
            case kAvataTypeSmall:
              
                return CGSizeMake(kAvataSmallW + kVerifiedW * 0.5, kAvataSmallH + kVerifiedH * 0.5);
                break;
                
            case kAvataTypeDefault:
                
                return CGSizeMake(kAvataDefaultW + kVerifiedW * 0.5, kAvataDefaultH + kVerifiedH * 0.5);
                break;
                
            case kAvataTypeBig:
                
                return CGSizeMake(kAvataBigW + kVerifiedW * 0.5, kAvataBigH + kVerifiedH * 0.5);
                break;
        }
    }
    
    #pragma mark 设置用户头像尺寸位置
    -(void)setType:(SAAvataType)type
    {
        _type = type;
        
        // 1、设置头像尺寸位置
        // 2、设置认证图标尺寸位置
        
        switch (type) {
            case kAvataTypeSmall:
                
                _icon.frame =  CGRectMake(0, 0, kAvataSmallW, kAvataSmallH);
                _verified.center = (CGPoint){_icon.frame.size.width, _icon.frame.size.height};
                _verified.bounds = CGRectMake(0, 0, kVerifiedW, kVerifiedH);
                break;
                
            case kAvataTypeBig:
                
                _icon.frame =  CGRectMake(0, 0, kAvataBigW, kAvataBigH);
                _verified.center = (CGPoint){_icon.frame.size.width, _icon.frame.size.height};
                _verified.bounds = CGRectMake(0, 0, kVerifiedW, kVerifiedH);
                break;
                
            default:
                
                _icon.frame =  CGRectMake(0, 0, kAvataDefaultW, kAvataDefaultH);
                _verified.center = (CGPoint){_icon.frame.size.width, _icon.frame.size.height};
                _verified.bounds = CGRectMake(0, 0, kVerifiedW, kVerifiedH);
                break;
        }
        
    }
    
    #pragma mark 设置用户数据
    -(void)setUser:(SAStatusUser *)user
    {
        // 1、设置头像图标内容
        _user = user;
        
        [_icon setImageWithURL:[NSURL URLWithString:user.profileImageUrl]
              placeholderImage:[UIImage imageNamed:@"avatar_default.png"]
                       options:SDWebImageRetryFailed | SDWebImageLowPriority];
        
        // 2、设置认证图标内容
        
        switch (user.verifiedType) {
            case kVerifiedTypeNone:
                
                _verified.hidden = YES;
                break;
                
            case kVerifiedTypePersonal:
                
                _verified.hidden = NO;
                _verified.image = [UIImage imageNamed:@"avatar_vip.png"];
                break;
                
            case kVerifiedTypeDaren:
                
                _verified.hidden = NO;
                _verified.image = [UIImage imageNamed:@"avatar_grassroot.png"];
                break;
                
            default:                //kVerifiedTypeOrgEnterprice、kVerifiedTypeOrgMedia、kVerifiedTypeOrgWebsite
                
                _verified.hidden = NO;
                _verified.image = [UIImage imageNamed:@"avatar_enterprise_vip.png"];
                break;
        }
        
    }
    
    // 返回用户头像占位图
    - (UIImage *)placeImageWithAvataType:(SAAvataType)avataType
    {
        switch (avataType) {
            case kAvataTypeSmall:
                
                return [UIImage imageNamed:@"avatar_default_small.png"];
                break;
                
            case kAvataTypeBig:
                
                return [UIImage imageNamed:@"avatar_default_big.png"];
                break;
                
            default:
                
                return [UIImage imageNamed:@"avatar_default.png"];
                break;
        }
    }
    
    #pragma mark 同时设置用户数据及头像尺寸
    - (void)setUser:(SAStatusUser *)user ofType:(SAAvataType)type
    {
        [self setUser:user];
        [self setType:type];
    }
    
    @end
    

    SAImageListView.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAImageListView.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-19.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  微博配图处理类
    
    #import <UIKit/UIKit.h>
    
    @interface SAImageListView : UIView
    
    @property (nonatomic, strong) NSArray *imageList;
    
    + (CGSize) sizeOfViewWithImageCount:(NSInteger)count;
    
    @end
    

    SAImageListView.m
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAImageListView.m
    //  SianWeibo
    //
    //  Created by yusian on 14-4-19.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  微博配图处理类
    
    #import "SAImageListView.h"
    #import "UIImageView+WebCache.h"
    
    @implementation SAImageListView
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            
            // 初始化9张图片并添加到View
            for (int i = 0; i < kImageCount; i++) {
                
                UIImageView *image = [[UIImageView alloc] init];
                
                [self addSubview:image];
            }
        }
        return self;
    }
    
    #pragma mark - 给每张图片内容赋值并计算图片尺寸与位置
    -(void)setImageList:(NSArray *)imageList
    {
        _imageList = imageList;
        
        // 1、取出所有子控件判断是否有需要展示图片
        
        // 2、设置展示图片及尺寸位置
        NSInteger imageCount = imageList.count;
        
        for (int i = 0; i < kImageCount; i++) {
            
            UIImageView *statusImages = self.subviews[i];
            
            if (i < imageCount) {   // 初始化9张图片,有图片url则显示,否则隐藏
                
                statusImages.hidden = NO;
                
                [statusImages setImageWithURL:[NSURL URLWithString:imageList[i][@"thumbnail_pic"]]
                       placeholderImage:[UIImage imageNamed:@"Icon.png"]
                                options:SDWebImageLowPriority | SDWebImageRetryFailed];
                
                if (imageCount == 1) {      // 1、一张配图情况
                    self.backgroundColor = [UIColor clearColor];                        // 设置背景色
                    statusImages.contentMode = UIViewContentModeScaleAspectFit;         // 设置图片保持宽高比
                    
                    // 设置尺寸位置
                    statusImages.frame = CGRectMake(0, 0, kStatusImageOneWH, kStatusImageOneWH);
                    
                } else {                    // 2、多张配图情况
                    self.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1];        // 设置背景色
                    statusImages.contentMode = UIViewContentModeScaleAspectFill;        // 设置图片正常填充
                    statusImages.clipsToBounds = YES;                                   // 裁剪边缘
                    
                    // 设置尺寸位置
                    NSInteger count = (imageCount == 4) ? 2 : 3;                        // 如果4张图片则按2列排,其他按3列排
                    CGFloat multipleWidth = kStatusImageMultipleWH;
                    CGFloat multipleHeight = kStatusImageMultipleWH;
                    NSInteger row = i / count;                                          // 计算行号0~n
                    NSInteger column = i % count;                                       // 计算列号0~n
                    statusImages.frame = CGRectMake(column * (kImageInterval + multipleWidth) + kImageInterval, row * (kImageInterval + multipleWidth) + kImageInterval, multipleWidth, multipleHeight);
                }
            } else {                // 初始化9张图片,有图片url则显示,否则隐藏
                statusImages.hidden = YES;
            }
            
        }
        
    }
    
    #pragma mark - 计算所有配图所占据的尺寸
    + (CGSize) sizeOfViewWithImageCount:(NSInteger)count
    {
        if (count == 1) {   // 只有一张图片展示大图
            return CGSizeMake(kStatusImageOneWH, kStatusImageOneWH);
        } else {            // 多张图片展示小图并计算多张图所占据的尺寸
            NSInteger columns = (count > 2 && count != 4) ? 3 : 2;  // 小于3张图或等于4张图按2列展示,否则按3列展示
            NSInteger rows = (count + columns - 1) / columns;       // 计算实际图片排列的行数,如果4张图无论是按2列还是按3列展示都是2行,所在不需要特殊处理
            return CGSizeMake(columns * (kStatusImageMultipleWH + kImageInterval) + kImageInterval, rows * (kStatusImageMultipleWH + kImageInterval) + kImageInterval);
        }
    }
    
    @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-10-20 13:40:06 | 显示全部楼层
    不回复不让看,顶一个:lol

    该用户从未签到

    发表于 2014-11-5 10:08:38 | 显示全部楼层
    感谢感谢感谢感谢!!
  • TA的每日心情
    发光
    2014-11-26 14:19
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2014-11-24 16:20:27 | 显示全部楼层
    上一章出现问题了、、、、、、、、、、
  • TA的每日心情

    2014-12-29 14:23
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2014-12-5 09:19:53 | 显示全部楼层
    想继续学习代码 上一章出现了问题 还好解决了
  • TA的每日心情
    得瑟
    2015-1-8 17:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-12-22 10:12:21 | 显示全部楼层
    学习,等学会了,也发一个,共享

    该用户从未签到

    发表于 2015-1-1 22:58:46 | 显示全部楼层
    谢谢谢谢谢谢谢谢谢谢谢谢楼主
  • TA的每日心情
    犯困
    2015-1-11 14:36
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2015-1-10 21:17:13 | 显示全部楼层
    学习学习再学习,顶起

    该用户从未签到

    发表于 2015-1-21 10:11:51 | 显示全部楼层
    请教一下楼主,如何把新浪微博中的解析出来的http:的链接生成一个小图片,进行点击?还有所以“@”的人有明显的标记(比如颜色是蓝色的)?
  • TA的每日心情
    开心
    2015-1-23 11:49
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2015-1-23 13:59:11 | 显示全部楼层
    好东西   ~~~
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

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

    GMT+8, 2024-4-25 07:31 , Processed in 0.060808 second(s), 24 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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