1、效果展示
2、更新内容
2.1 优化配图显示方式,在Gif图片下方增加Gif图标;
2.2 优化微博显示方式:调节每条微博的边距,修改微博背景颜色;
2.3 增加微博功能菜单栏,每次微博下方添加三个按钮;
3、设计说明
3.1 设计配图处理类SAImageView,判断当前是否为Gif图片,Gif图片展示时在图片右下角增加一个Gif图标,即在原有的UIImageView上添加一个UIImageView
3.2. 修改SAStatusCell类,优化Cell展示方式
3.2.1 设置backgroundView,并拉伸图片
3.2.2 重写SAStatusCell的setFrame方法,缩小Cell的大小,留出边距
3.2.3 修改框架模型SAStatusFrame类,调整Cell中相关受影响的元素Frame值,并将Cell高度增加一个功能菜单栏的高度
3.3 设计一个SAStatusDock类,用来展示Cell的功能菜单栏
3.3.1 SAStatusDock初始化时设置尺寸位置,并设置autoresizingMask属性为UIViewAutoresizingFlexibleTopMargin,实现自动伸缩,使菜单栏永远在Cell的底部
3.3.2 设置三个按钮并设置按钮的尺寸文字图标,将按钮添加到功能菜单栏
3.3.3 微调美化
3.4 整体微调美化
4、关键代码
SACommon.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | // //? 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 kBGColor??????????? kColor(239, 239, 244)?????????????????????????? // 全局背景颜色 #define kMBScreenNameColor? kColor(240, 100, 20)??????????????????????????? // 会员用户昵称颜色 #define kScreenNameColor??? kColor(0, 0, 0)???????????????????????????????? // 普通用户昵称颜色 #define kTimeColor????????? kColor(200, 100, 30)??????????????????????????? // 微博发表时间显示颜色 #define kCellMargins??????? (kInterval * 0.5)?????????????????????????????? // 单元格两边边距 //#define kCellInterval?????? kInterval?????????????????????????????????????? // 单元格相互之间间隔 // SAImageListView 配图处理相关 #define kImageCount???????? 9?????????????????????????????????????????????? // 微博配图最大配图数 #define kImageInterval????? 5?????????????????????????????????????????????? // 微博配图间隔 #define kStatusImageOneWH?? 100???????????????????????????????????????????? // 一张配图尺寸 #define kStatusImageMuWH??? 80????????????????????????????????????????????? // 多總配图尺寸 // SAStatusDock 功能菜单栏 #define kCellDefaultHeight? 44????????????????????????????????????????????? // TableViewCell默认高度 #define kStatusDockHeight?? 35????????????????????????????????????????????? // 功能菜单栏高度 #endif? // __SACOMMON_H__ |
SAImageView.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // //? SAImageView.h //? SianWeibo // //? Created by yusian on 14-4-20. //? Copyright (c) 2014年 小龙虾论坛. All rights reserved. // ? #import <UIKit/UIKit.h> ? @interface SAImageView : UIImageView ? @property (nonatomic, copy) NSString *picUrl; ? @end |
SAImageView.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | // //? SAImageView.m //? SianWeibo // //? Created by yusian on 14-4-20. //? Copyright (c) 2014年 小龙虾论坛. All rights reserved. // ? #import "SAImageView.h" #import "SAStatusTool.h" ? @interface SAImageView() { ????UIImageView *_gifView; } @end ? @implementation SAImageView ? #pragma mark 初始化View,将gif图标附加到该View上 - (id)initWithFrame:(CGRect)frame { ????self = [super initWithFrame:frame]; ????if (self) { ????????? ????????_gifView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"timeline_image_gif.png"]]; ????????? ????????[self addSubview:_gifView]; ????????? ????} ????return self; } ? #pragma mark 设置图片url -(void)setPicUrl:(NSString *)picUrl { ????_picUrl = picUrl; ????? ????[SAStatusTool statusToolInsteadView:self setImageWithURLString:picUrl placeholderImage:[UIImage imageNamed:@"timeline_image_loading.png"]]; ????? ????// 在设置图片url同时判断该图是否为GIF图片,如果是则显示Gif图标 ????_gifView.hidden = ![picUrl.lowercaseString hasSuffix:@".gif"]; } ? #pragma mark 重写setFrame方法 -(void)setFrame:(CGRect)frame { ????[super setFrame:frame]; ????? ????// 设置图片Frame的时候将Gif图标的Frame设置好 ????CGSize gifViewSize = _gifView.frame.size; ????_gifView.frame = CGRectMake(frame.size.width - gifViewSize.width, frame.size.height - gifViewSize.height, gifViewSize.width, gifViewSize.height); } ? @end |
SAStatusDock.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | // //? SAStatusDock.h //? SianWeibo // //? Created by yusian on 14-4-20. //? Copyright (c) 2014年 小龙虾论坛. All rights reserved. //? 微博Dock ? #import <UIKit/UIKit.h> ? @interface SAStatusDock : UIImageView ? @end |
SAStatusDock.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | // //? SAStatusDock.m //? SianWeibo // //? Created by yusian on 14-4-20. //? Copyright (c) 2014年 小龙虾论坛. All rights reserved. //? 微博Dock ? #import "SAStatusDock.h" #import "UIImage+SA.h" #import "NSString+SA.h" ? @interface SAStatusDock () { ????UIButton??? *_left; ????UIButton??? *_middle; ????UIButton??? *_right; } @end ? @implementation SAStatusDock ? - (id)initWithFrame:(CGRect)frame { ????self = [super initWithFrame:frame]; ????if (self) { ????????? ????????// 设置Dock的尺寸位置 ????????CGFloat dockWidth = [UIScreen mainScreen].bounds.size.width - 2 * kCellMargins; ????????self.frame = CGRectMake(0, kCellDefaultHeight - kCellMargins - kStatusDockHeight, dockWidth, kStatusDockHeight); ????????? ????????// Dock贴紧父控件底部,即保持在Cell底部 ????????self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; ????????? ????????// 接受用户交互 ????????self.userInteractionEnabled = YES; ????????? ????????// 添加3个按钮 ????????[self addButtonWithTitle:@"转发" andImage:@"timeline_icon_comment.png" backgroundImage:@"timeline_card_leftbottom.png" buttonIndex:0]; ????????[self addButtonWithTitle:@"评论" andImage:@"timeline_icon_retweet.png" backgroundImage:@"timeline_card_middlebottom.png" buttonIndex:1]; ????????[self addButtonWithTitle:@"赞" andImage:@"timeline_icon_unlike.png" backgroundImage:@"timeline_card_rightbottom.png" buttonIndex:2]; ????} ????return self; } ? #pragma mark 添加功能菜单栏按钮 - (void)addButtonWithTitle:(NSString *)title andImage:(NSString *)imageName backgroundImage:(NSString *)backgroundImageName buttonIndex:(NSInteger)index { ????// 按钮基本属性设置 ????UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; ????[button setTitle:title forState:UIControlStateNormal];????????????????????????? // 设置文字 ????[button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];?????? // 文字颜色 ????button.titleLabel.font = [UIFont systemFontOfSize:12];????????????????????????? // 文字大小 ????[button setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal]; // 按钮图标 ????button.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);???????????????????????? // 图文间距 ????? ????// 按钮背景图片 ????[button setBackgroundImage:[UIImage resizeImage:backgroundImageName] forState:UIControlStateNormal]; ????[button setBackgroundImage:[UIImage resizeImage:[backgroundImageName fileAppend:@"_highlight"]] forState:UIControlStateHighlighted]; ????? ????// 按钮尺寸位置 ????CGFloat buttonWidth = self.frame.size.width / 3; ????button.frame = CGRectMake(index * buttonWidth, 0, buttonWidth, kStatusDockHeight); ????? ????// 添加按钮间间隔图片 ????if (index) { ????????UIImageView *cardButton = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"timeline_card_bottom_line.png"]]; ????????[self addSubview:cardButton]; ????????cardButton.center = CGPointMake(button.frame.origin.x, kStatusDockHeight * 0.5); ????} ????[self addSubview:button]; } ? @end</per> SAStatusCell.h <pre lang="objc" line="1">// //? 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | // //? SAStatusCell.m //? SianWeibo // //? Created by yusian on 14-4-18. //? Copyright (c) 2014年 小龙虾论坛. All rights reserved. //? 微博单元格类 ? #import "SAStatusCell.h" #import "SAAvata.h" #import "SAImageListView.h" #import "SAStatusDock.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;????? // 转发体配图 ????SAStatusDock??? *_statusDock;?? // 功能菜单 } @end ? @implementation SAStatusCell ? #pragma mark 初始化单元格元素 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { ????self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; ????if (self) { ????????? ????????self.backgroundColor = [UIColor clearColor]; ????????self.backgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"common_card_background.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5]]; ????????self.selectedBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"common_card_background_highlighted.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5]]; ????????? ????????// 1、头像 ????????_profile = [[SAAvata alloc] init]; ????????_profile.backgroundColor = [UIColor clearColor]; ????????[self.contentView addSubview:_profile]; ????????? ????????// 2、昵称 ????????_screenName = [[UILabel alloc] init]; ????????_screenName.backgroundColor = [UIColor clearColor]; ????????_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.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]; ????????? ????????// 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]; ????????? ????????// 11、添加功能菜单 ????????_statusDock = [[SAStatusDock alloc] init]; ????????[self.contentView addSubview:_statusDock]; ????????? ????} ????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 重写frame方法设置Cell宽度 // 该方法会被调用2次 -(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 设置单元格标识 + (NSString *)ID { ????return @"StatusCell"; } ? @end |
5、源码下载
链接: http://pan.baidu.com/s/1jGDRhI2 密码: 5ilj