年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 17187|回复: 39

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

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

    [LV.9]以坛为家II

    发表于 2014-4-21 14:18:38 | 显示全部楼层 |阅读模式
    1、效果展示

    iOS 模拟器屏幕快照“2014年4月21日 下午1.45.27”.png

    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
    [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 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
    [Objective-C] 纯文本查看 复制代码
    //
    //  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
    [Objective-C] 纯文本查看 复制代码
    //
    //  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
    [Objective-C] 纯文本查看 复制代码
    //
    //  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
    [Objective-C] 纯文本查看 复制代码
    //
    //  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
    

    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 "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、源码下载
    游客,如果您要查看本帖隐藏内容请回复

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

  • TA的每日心情
    高兴
    2015-10-10 10:21
  • 签到天数: 44 天

    [LV.5]常住居民I

    发表于 2015-7-9 23:14:03 | 显示全部楼层
    SAStatus类中,setSource方法里需要对rangeOfString:方法调用的返回结果做判断。不然当source字段为空时,会引起程序崩溃。

    该用户从未签到

    发表于 2014-6-6 17:03:23 | 显示全部楼层
    好不错的帖子,感谢分享

    该用户从未签到

    发表于 2014-11-5 14:26:54 | 显示全部楼层
    好不错的帖子,感谢分享
  • TA的每日心情
    发光
    2014-11-26 14:19
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2014-11-26 14:23:48 | 显示全部楼层
    继续来看看
  • TA的每日心情

    2014-12-10 10:56
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-12-2 09:47:01 | 显示全部楼层
    好复杂啊,看的好累
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

     楼主| 发表于 2014-12-2 12:54:56 | 显示全部楼层
    朱彬磊 发表于 2014-12-2 09:47
    好复杂啊,看的好累

    那肯定还是要费点心的,如果都跟切韭菜一样了那ios开发人员将何去何从...
    不过也没你想像得那么难,上路了就容易...
  • TA的每日心情
    得瑟
    2015-1-8 17:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2014-12-22 10:15:20 | 显示全部楼层
    楼主还有其他小型的项目资源可以借鉴下么
  • TA的每日心情

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

    [LV.2]偶尔看看I

    发表于 2014-12-22 16:51:28 | 显示全部楼层
    写着写着 就看了后面忘了前面了 哎 感觉自己脑子好不够用啊 而且感觉如果让我自己写 我无法封装的这么好
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

     楼主| 发表于 2014-12-23 08:59:42 | 显示全部楼层
    warmlight 发表于 2014-12-22 16:51
    写着写着 就看了后面忘了前面了 哎 感觉自己脑子好不够用啊 而且感觉如果让我自己写 我无法封装的这么好

    先模仿,再尝试着应用,慢慢地就变成你自己的了...别急
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

     楼主| 发表于 2014-12-23 09:00:41 | 显示全部楼层
    hnxyzhw 发表于 2014-12-22 10:15
    楼主还有其他小型的项目资源可以借鉴下么

    有时间会再上几个项目,期待一下。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

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

    GMT+8, 2024-4-25 15:52 , Processed in 0.065875 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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