Sian 发表于 2014-4-21 14:18:38

ios实战开发之仿新浪微博(第八讲:微博数据展示三)

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
//
//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 (.bounds.size.height == 568)

// 用MyLog替代NSLog,调试时输出日志,正式发布时自动取消日志输出代码
#ifdef DEBUG
#define MyLog(...) NSLog(__VA_ARGS__)
#else
#define MyLog(...)
#endif

// SAOAuthController:OAuth认证
#define kOAuthURL     // 新浪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                      // 用户昵称字号
#define kMBIconWH         12                                              // 会员图标尺寸
#define kTimeFont                           // 发表时间字号
#define kSourceFont         kTimeFont                                       // 微博来源字号
#define kTextFount                            // 微博正文字号
#define kReScreenNameFont                     // 转发微博体昵称字号
#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)   
#define kBGColor            kColor(239, 239, 244)                           // 全局背景颜色
#define kMBScreenNameColorkColor(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 kCellDefaultHeight44                                              // TableViewCell默认高度
#define kStatusDockHeight   35                                              // 功能菜单栏高度

#endif// __SACOMMON_H__

SAImageView.h
//
//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
//
//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 = ;
    if (self) {
      
      _gifView = [ initWithImage:];
      
      ;
      
    }
    return self;
}

#pragma mark 设置图片url
-(void)setPicUrl:(NSString *)picUrl
{
    _picUrl = picUrl;
   
    ];
   
    // 在设置图片url同时判断该图是否为GIF图片,如果是则显示Gif图标
    _gifView.hidden = !;
}

#pragma mark 重写setFrame方法
-(void)setFrame:(CGRect)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
//
//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
//
//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 = ;
    if (self) {
      
      // 设置Dock的尺寸位置
      CGFloat dockWidth = .bounds.size.width - 2 * kCellMargins;
      self.frame = CGRectMake(0, kCellDefaultHeight - kCellMargins - kStatusDockHeight, dockWidth, kStatusDockHeight);
      
      // Dock贴紧父控件底部,即保持在Cell底部
      self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
      
      // 接受用户交互
      self.userInteractionEnabled = YES;
      
      // 添加3个按钮
      ;
      ;
      ;
    }
    return self;
}

#pragma mark 添加功能菜单栏按钮
- (void)addButtonWithTitle:(NSString *)title andImage:(NSString *)imageName backgroundImage:(NSString *)backgroundImageName buttonIndex:(NSInteger)index
{
    // 按钮基本属性设置
    UIButton *button = ;
    ;                        // 设置文字
    forState:UIControlStateNormal];       // 文字颜色
    button.titleLabel.font = ;                        // 文字大小
    forState:UIControlStateNormal]; // 按钮图标
    button.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);                         // 图文间距
   
    // 按钮背景图片
    forState:UIControlStateNormal];
    ] forState:UIControlStateHighlighted];
   
    // 按钮尺寸位置
    CGFloat buttonWidth = self.frame.size.width / 3;
    button.frame = CGRectMake(index * buttonWidth, 0, buttonWidth, kStatusDockHeight);
   
    // 添加按钮间间隔图片
    if (index) {
      UIImageView *cardButton = [ initWithImage:];
      ;
      cardButton.center = CGPointMake(button.frame.origin.x, kStatusDockHeight * 0.5);
    }
    ;
}

@end

SAStatusCell.h
//
//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
//
//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 = ;
    if (self) {
      
      self.backgroundColor = ;
      self.backgroundView = [ initWithImage:[ stretchableImageWithLeftCapWidth:5 topCapHeight:5]];
      self.selectedBackgroundView = [ initWithImage:[ stretchableImageWithLeftCapWidth:5 topCapHeight:5]];
      
      // 1、头像
      _profile = [ init];
      _profile.backgroundColor = ;
      ;
      
      // 2、昵称
      _screenName = [ init];
      _screenName.backgroundColor = ;
      _screenName.font = kScreenNameFount;
      ;
      
      // 2.1 会员图标
      _mbIcon = [ init];
      _mbIcon.image = ;
      ;
      
      // 3、时间
      _time = [ init];
      _time.backgroundColor = ;
      _time.font = kTimeFont;
      _time.textColor = kTimeColor;
      ;
      
      // 4、来源
      _source = [ init];
      _source.backgroundColor = ;
      _source.font = kSourceFont;
      _source.textColor = ;
      ;
      
      // 5、正文
      _text = [ init];
      _text.backgroundColor = ;
      _text.font = kTextFount;
      _text.numberOfLines = 0;
      ;
      
      // 6、配图
      _image = [ init];
      _image.contentMode = UIViewContentModeScaleAspectFit;
      ;
      
      // 7、转发体视图
      _retweet = [ init];
      _retweet.image = [ stretchableImageWithLeftCapWidth:25 topCapHeight:10];
      ;
      
      // 8、转发体昵称
      _reScreenName = [ init];
      _reScreenName.font = kReScreenNameFont;
      _reScreenName.backgroundColor = ;
      _reScreenName.textColor = ;
      ;
      
      // 9、转发体正文
      _reText = [ init];
      _reText.numberOfLines = 0;
      _reText.font = kReTextFont;
      _reText.backgroundColor = ;
      ;
      
      // 10、转发体配图
      _reImage = [ init];
      _reImage.contentMode = UIViewContentModeScaleAspectFit;
      ;
      
      // 11、添加功能菜单
      _statusDock = [ init];
      ;
      
    }
    return self;
}

#pragma mark - 设置单元格
-(void)setStatusFrame:(SAStatusFrame *)statusFrame
{
   
    _statusFrame = statusFrame;
   
    // 1、设置子控件内容
    ;
   
    // 2、计算子控件Frame
    ;
}

#pragma mark 设置单元格内容
- (void)statusFrameSettingView
{
    SAStatus *status = self.statusFrame.status;
   
    // 1、设置头像
    ;
   
    // 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 = ;
      
      // 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 = ; // 时间动态显示,时间尺寸动态计算
    _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;
   
    ;
}

#pragma mark 设置单元格标识
+ (NSString *)ID
{
    return @"StatusCell";
}

@end

5、源码下载
**** Hidden Message *****
相关主题链接
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实战开发之仿新浪微博(小龙虾发布版)

Miul 发表于 2015-7-9 23:14:03

SAStatus类中,setSource方法里需要对rangeOfString:方法调用的返回结果做判断。不然当source字段为空时,会引起程序崩溃。

齐坦 发表于 2014-6-6 17:03:23

好不错的帖子,感谢分享

panzilong 发表于 2014-11-5 14:26:54

好不错的帖子,感谢分享

yipangzi 发表于 2014-11-26 14:23:48

继续来看看

朱彬磊 发表于 2014-12-2 09:47:01

好复杂啊,看的好累

Sian 发表于 2014-12-2 12:54:56

朱彬磊 发表于 2014-12-2 09:47
好复杂啊,看的好累

那肯定还是要费点心的,如果都跟切韭菜一样了那ios开发人员将何去何从...
不过也没你想像得那么难,上路了就容易...

hnxyzhw 发表于 2014-12-22 10:15:20

楼主还有其他小型的项目资源可以借鉴下么

warmlight 发表于 2014-12-22 16:51:28

写着写着 就看了后面忘了前面了 哎 感觉自己脑子好不够用啊 而且感觉如果让我自己写 我无法封装的这么好

Sian 发表于 2014-12-23 08:59:42

warmlight 发表于 2014-12-22 16:51
写着写着 就看了后面忘了前面了 哎 感觉自己脑子好不够用啊 而且感觉如果让我自己写 我无法封装的这么好

先模仿,再尝试着应用,慢慢地就变成你自己的了...别急

Sian 发表于 2014-12-23 09:00:41

hnxyzhw 发表于 2014-12-22 10:15
楼主还有其他小型的项目资源可以借鉴下么

有时间会再上几个项目,期待一下。
页: [1] 2 3 4
查看完整版本: ios实战开发之仿新浪微博(第八讲:微博数据展示三)