Sian 发表于 2014-4-10 20:50:13

ios实战开发之代码创建Cell(演示新浪微博)

本帖最后由 Sian 于 2014-4-18 14:02 编辑

1、效果演示

http://player.youku.com/player.php/sid/XNjk3MDQyMDA4/v.swf

2、设计说明
2.0 设计草图


2.1 模型说明
2.1.1 SAWeibo类:该类主要功能是将基本数据抽象成数据模型,将数据处理思想转换成面向对象的理念;
2.1.2 SAWeiboFrame类:该类是新增加的一个类,将各视图尺寸位置的设置单独抽象出来创建一个视图框架模型,该模型中包含了数据模型,给每条微博提供数据源及各子视图子控件提供位置与尺寸服务;
2.1.3 SAWeiboCell类:该类主要功能是创建TableView中每个Cell的内容,包含数据与视图,因此将SAWeiboFrame添加给该类的一个成员变量,调用SAWeibo类与SAWeiboFrame类完成微博展示功能;

2.2 基本步骤
2.2.1 删除原有的控制器,新建一个控制器SAWeiboController直接继承自UITableViewController,删除storyboard中的view,新建一个UITableView并将UITableView的类设置为新创建的控制器
2.2.2 新建一个类SAWeiboCell继承自UITabeViewCell,该类主要功能在2.1 模型说明中已描述;
2.2.3 在控制器SAWeiboController中实现必须实现的几个方法,如numberOfRowsInSection、cellForRowAtIndexPath、heightForRowAtIndexPath等方法
2.2.4 在实现cellForRowAtIndexPath方法前需要创建SAWeiboCell类,并在该类中实现Cell创建的initWithStyle:reuseIdentifier:方法,添加cell内部需要的子控件(此时只管添加控件暂不关心控件的尺寸与位置);
2.2.5 创建数据模型SAWeibo类,增加相应的数据属性;
2.2.6 创建视图框架模型SAWeiboFrame类,增加相应的数据属性并将数据模型设置成该模型的属性;
2.2.7 重写setWeibo方法,将数据模型赋值的同时将所有子控件的尺寸与位置进行计算确定、将在最后计算出每个Cell的高度
2.2.8 将计算得出来的值分别写到各属性中,回到控制器完善控制器未完成的配置;
2.2.9 将数据模型赋值,将视图框架模型赋值,并将相关属性结果回写到numberOfRowsInSection、cellForRowAtIndexPath、heightForRowAtIndexPath方法中

3、关键代码
SAWeibo.h
//
//SAWeibo.h
//Weibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 yusian. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface SAWeibo : NSObject

@property (nonatomic, copy)   NSString    *icon;      // 头像
@property (nonatomic, copy)   NSString    *name;      // 昵称
@property (nonatomic, assign)   BOOL      isVip;      // vip标识
@property (nonatomic, copy)   NSString    *time;      // 发表时间
@property (nonatomic, copy)   NSString    *source;    // 微博来源
@property (nonatomic, copy)   NSString    *content;   // 微博内容
@property (nonatomic, copy)   NSString    *image;   // 微博配图

+ (id)weiboWithDict:(NSDictionary *)dict;               // 模型赋值类方法
- (id)initWithDict:(NSDictionary *)dict;                // 模型赋值对象方法

@end

SAWeibo.m
//
//SAWeibo.m
//Weibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 yusian. All rights reserved.
//

#import "SAWeibo.h"

@implementation SAWeibo

+ (id)weiboWithDict:(NSDictionary *)dict
{
    return [ initWithDict:dict];    // 调用对象方法初始化数据模型
}

// 取出字典中的每个Key中对应的值赋值给数据模型
- (id)initWithDict:(NSDictionary *)dict
{
    if (self = ) {
      self.icon = dict[@"icon"];            // 头像图片名称
      self.name = dict[@"name"];            // 昵称
      self.time = dict[@"time"];            // 发表时间
      self.source = dict[@"source"];          // 微博来源
      self.isVip = boolValue];// vip标识,Number类型转成BOOL类型
      self.content = dict[@"content"];      // 微博正文
      self.image = dict[@"image"];            // 微博配图图片名称
    }
    return self;
}

@end

SAWeiboFrame.h
//
//SAWeiboFrame.h
//Weibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 yusian. All rights reserved.
//

#import <Foundation/Foundation.h>
#define kIconWH 40                                  // 头像宽高
#define kInterval 10                              // 全局间距
#define kVipWH14                                  // vip标识宽高
#define kImageWH 200                              // 微博配图宽高
#define kNameFont       // 昵称字号大小
#define kTimeFont       // 发表时间字号大小
#define kSourceFont     // 微博来源字号大小
#define kContentFont    // 微博正文字号大小
@class SAWeibo;

@interface SAWeiboFrame : NSObject

@property (nonatomic, assign, readonly) CGRecticonViewFrame;      // 头像尺寸位置
@property (nonatomic, assign, readonly) CGRectnameLabelFrame;   // 昵称尺寸位置
@property (nonatomic, assign, readonly) CGRecttimeLabelFrame;   // 发表时间尺寸位置
@property (nonatomic, assign, readonly) CGRectvipViewFrame;       // vip标识尺寸位置
@property (nonatomic, assign, readonly) CGRectsourceLabelFrame;   // 微博来源尺寸位置
@property (nonatomic, assign, readonly) CGRectcontentLabelFrame;// 微博正文尺寸位置
@property (nonatomic, assign, readonly) CGRectimageViewFrame;   // 微博配图尺寸位置
@property (nonatomic, assign, readonly) CGFloat cellHeight;         // 每条微博Cell高度

@property (nonatomic, strong) SAWeibo *weibo;                     // 数据模型

@end

SAWeiboFrame.m
//
//SAWeiboFrame.m
//Weibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 yusian. All rights reserved.
//

#import "SAWeiboFrame.h"
#import "SAWeibo.h"

@implementation SAWeiboFrame

// 在数据模型set方法中将各子视图的尺寸大小及每条微博的行高进行计算与确定
- (void)setWeibo:(SAWeibo *)weibo
{
    _weibo = weibo;   // 将创建好的模型对象赋值给成员变量,让模型数据成为视图框架模型的属性

    // 1、头像
    CGFloat iconX = kInterval;
    CGFloat iconY = kInterval;
    _iconViewFrame = CGRectMake(iconX, iconY, kIconWH, kIconWH);
   
    // 2、昵称
    CGFloat nameX = CGRectGetMaxX(_iconViewFrame) + kInterval;
    // CGRectGetMaxX(_iconViewFrame)为取头像Frame中X最大值
   
    CGFloat nameY = iconY;
    CGSize nameSize = ;
    // 字符串方法,意为该字符串在某种字体状态下所占据的尺寸
   
    _nameLabelFrame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height);
   
    // 3、vip
    CGFloat vipX = CGRectGetMaxX(_nameLabelFrame) + kInterval;
    CGFloat vipY = iconY;
    _vipViewFrame = CGRectMake(vipX, vipY, kVipWH, kVipWH);
   
    // 4、时间
    CGFloat timeX = nameX;
    CGFloat timeY = CGRectGetMaxY(_nameLabelFrame) + kInterval;
    CGSize timeSize = ;
    _timeLabelFrame = CGRectMake(timeX, timeY, timeSize.width, timeSize.height);
   
    // 5、来源
    CGFloat sourceX = CGRectGetMaxX(_timeLabelFrame) + kInterval;
    CGFloat sourceY = timeY;
    NSString *sourceText = ;
    CGSize sourceSize = ;
    // 计算尺寸应为实际显示内容的尺寸,所以取拼串后字符串的sizeWithFont:方法
   
    _sourceLabelFrame = CGRectMake(sourceX, sourceY, sourceSize.width, sourceSize.height);
   
    // 6、正文
    CGFloat contentX = iconX;
    CGFloat contentY = MAX(CGRectGetMaxY(_iconViewFrame), CGRectGetMaxY(_timeLabelFrame)) + kInterval;
    // 正文与上面子视图保持一个全局间隔距离,但无法确定头像与发表时间哪个子视图下边缘Y值更大,所以利用宏MAX(A, B)对这两个子视图进行比较,以最大值为标准
   
    CGFloat contentWidth = 320 - 2 * kInterval;
    // 正文宽度保持屏幕两侧预算一个全局间隔距离即可
   
    CGSize contentSize = ;
    _contentLabelFrame = CGRectMake(contentX, contentY, contentSize.width, contentSize.height);
   
    // 7、配图
    if (self.weibo.image) {
      CGFloat imageX = contentX;
      CGFloat imageY = CGRectGetMaxY(_contentLabelFrame) + kInterval;
      _imageViewFrame = CGRectMake(imageX, imageY, kImageWH, kImageWH);
      
      // 如果有配图,则每条微博高度以配图下边缘Y值为基准
      _cellHeight = CGRectGetMaxY(_imageViewFrame) + kInterval;
    } else {
      // 如果没有配置,则每条微博高度以正文下边缘Y值为基准
      _cellHeight = CGRectGetMaxY(_contentLabelFrame) + kInterval;
    }
   
}

@end

SAWeiboCell.h
//
//SAWeiboCell.h
//Weibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 yusian. All rights reserved.
//

#import <UIKit/UIKit.h>
@class SAWeiboFrame;

@interface SAWeiboCell : UITableViewCell

@property (nonatomic, strong) SAWeiboFrame *weiboFrame;   // 让视图框架模型成为Cell模型的属性

+ (NSString *)ID;       // 封装tableView的缓存cell标识

@end

SAWeiboCell.m
//
//SAWeiboCell.m
//Weibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 yusian. All rights reserved.
//

#import "SAWeiboCell.h"
#import "SAWeiboFrame.h"
#import "SAWeibo.h"

@interface SAWeiboCell ()   // 类扩展成员变量
{
    UIImageView   *_iconView;         // 头像
    UIImageView   *_vipView;          // vip标识
    UILabel         *_nameLabel;      // 昵称
    UILabel         *_sourceLabel;      // 微博来源
    UILabel         *_timeLabel;      // 发表时间
    UILabel         *_contentLabel;   // 微博正文
    UIImageView   *_imageView;      // 微博配图
}
@end

@implementation SAWeiboCell

#pragma mark cell初始化方法
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = ) {
      
      // 1、头像
      _iconView = [ init];
      ;
      
      // 2、昵称
      _nameLabel = [ init];
      _nameLabel.font = kNameFont;
      ;
      
      // 3、vip标识
      _vipView = [ init];
      _vipView.image = ;
      ;
      
      // 4、发表时间
      _timeLabel = [ init];
      _timeLabel.font = kTimeFont;
      _timeLabel.textColor = ;
      ;
      
      // 5、微博来源
      _sourceLabel = [ init];
      _sourceLabel.font = kSourceFont;
      _sourceLabel.textColor = ;
      ;
      
      // 6、正文
      _contentLabel = [ init];
      _contentLabel.font = kContentFont;
      ;
      
      // 7、配图
      _imageView = [ init];
      ;
      
    }
    return self;
}

#pragma mark 成员变量weiboFrame的set方法
- (void)setWeiboFrame:(SAWeiboFrame *)weiboFrame
{
    _weiboFrame = weiboFrame;   // 将创建好的Frame对象赋值给成员变量
    ;         // 设置子视图数据
    ;      // 设置子视图尺寸及位置
}

// 调用微博数据模型设置每条微博中子视图数据内容
- (void)settingView
{
    // 1、头像
    _iconView.image = ;
   
    // 2、昵称
    _nameLabel.text = _weiboFrame.weibo.name;
    if (_weiboFrame.weibo.isVip) {
      _nameLabel.textColor = ;      // 带vip标识的用户昵称显示为红色
    } else {
      _nameLabel.textColor = ;    // 非vip用户昵称显示为黑色
    }
   
    // 3、vip
    _vipView.hidden = !_weiboFrame.weibo.isVip;

    // 4、时间
    _timeLabel.text = _weiboFrame.weibo.time;
   
    // 5、来源
    _sourceLabel.text = ;
   
    // 6、正文
    _contentLabel.text = _weiboFrame.weibo.content;
    _contentLabel.numberOfLines = 0;                  // 多行文本
   
    // 7、配图
    if (_weiboFrame.weibo.image) {
      _imageView.hidden = NO;
      _imageView.image = ;
      _imageView.contentMode = UIViewContentModeScaleAspectFit;
      // 图片显示模式为最大化填充,非拉伸效果,不改变图片宽高比
      
    } else {
      _imageView.hidden = YES;
    }
}

// 调用子视图框架模型设置每条微博中子视图的尺寸及位置
- (void)settingFrame
{
    // 1、头像
    _iconView.frame = _weiboFrame.iconViewFrame;
   
    // 2、昵称
    _nameLabel.frame = _weiboFrame.nameLabelFrame;
   
    // 3、vip
    _vipView.frame = _weiboFrame.vipViewFrame;
   
    // 4、时间
    _timeLabel.frame = _weiboFrame.timeLabelFrame;
   
    // 5、来源
    _sourceLabel.frame = _weiboFrame.sourceLabelFrame;
   
    // 6、正文
    _contentLabel.frame = _weiboFrame.contentLabelFrame;
   
    // 7、配图
    _imageView.frame = _weiboFrame.imageViewFrame;
}

// 封装tableView缓存中重复利用Cell的标识
+(NSString *)ID
{
    return @"Weibo";
}

@end

SAWeiboController.h
//
//SAWeiboController.h
//Weibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 yusian. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface SAWeiboController : UITableViewController

@end

SAWeiboController.m
//
//SAWeiboController.m
//Weibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 yusian. All rights reserved.
//

#import "SAWeiboController.h"
#import "SAWeibo.h"
#import "SAWeiboFrame.h"
#import "SAWeiboCell.h"

@interface SAWeiboController ()
{
    NSMutableArray *_weiboFrames;       // 可变数据保存视图框架模型
}

@end

@implementation SAWeiboController

- (void)viewDidLoad
{
    ;
    _weiboFrames = ;
   
    // 将plist文件读取到数据,原始数据
    NSArray *array = pathForResource:@"Weibo.plist" ofType:nil]];
   
    for (NSDictionary *dict in array) {
      SAWeiboFrame *weiboFrame = [ init]; // 创建视图框架模型
      weiboFrame.weibo = ;      // 将原始数据转换成数据模型
      ;                  // 视图框架模型保存到数组
    }
   
    // 利用tableView缓存数据机制中的一个特别处理方式,如果缓存中没有则调用相关类创建
    forCellReuseIdentifier:];
    /*等同于以下代码
    if (cell == nil) {
      cell = [ initWithStyle:UITableViewCellStyleDefault reuseIdentifier:];
    }*/
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _weiboFrames.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 缓存中取相关对象重复利用
    SAWeiboCell *cell = ];
   
    // 将数据视图框架模型(该模型中包含了数据模型)赋值给Cell,展示每条微博内容
    cell.weiboFrame = _weiboFrames;
   
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 调用视图框架模型返回每条微博动态高度
    return cellHeight];
}

@end

4、源代码下载
**** Hidden Message *****
页: [1]
查看完整版本: ios实战开发之代码创建Cell(演示新浪微博)