年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6334|回复: 0

[实用控件] ios实战开发之代码创建Cell(演示新浪微博)

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

    [LV.9]以坛为家II

    发表于 2014-4-10 20:50:13 | 显示全部楼层 |阅读模式
    本帖最后由 Sian 于 2014-4-18 14:02 编辑

    1、效果演示



    2、设计说明
    2.0 设计草图
    001.png

    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
    1. //
    2. //  SAWeibo.h
    3. //  Weibo
    4. //
    5. //  Created by yusian on 14-4-10.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import <Foundation/Foundation.h>
    9. @interface SAWeibo : NSObject
    10. @property (nonatomic, copy)     NSString    *icon;      // 头像
    11. @property (nonatomic, copy)     NSString    *name;      // 昵称
    12. @property (nonatomic, assign)   BOOL        isVip;      // vip标识
    13. @property (nonatomic, copy)     NSString    *time;      // 发表时间
    14. @property (nonatomic, copy)     NSString    *source;    // 微博来源
    15. @property (nonatomic, copy)     NSString    *content;   // 微博内容
    16. @property (nonatomic, copy)     NSString    *image;     // 微博配图
    17. + (id)weiboWithDict:(NSDictionary *)dict;               // 模型赋值类方法
    18. - (id)initWithDict:(NSDictionary *)dict;                // 模型赋值对象方法
    19. @end
    复制代码
    SAWeibo.m
    1. //
    2. //  SAWeibo.m
    3. //  Weibo
    4. //
    5. //  Created by yusian on 14-4-10.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import "SAWeibo.h"
    9. @implementation SAWeibo
    10. + (id)weiboWithDict:(NSDictionary *)dict
    11. {
    12.     return [[self alloc] initWithDict:dict];    // 调用对象方法初始化数据模型
    13. }
    14. // 取出字典中的每个Key中对应的值赋值给数据模型
    15. - (id)initWithDict:(NSDictionary *)dict
    16. {
    17.     if (self = [super init]) {
    18.         self.icon = dict[@"icon"];              // 头像图片名称
    19.         self.name = dict[@"name"];              // 昵称
    20.         self.time = dict[@"time"];              // 发表时间
    21.         self.source = dict[@"source"];          // 微博来源
    22.         self.isVip = [dict[@"vip"] boolValue];  // vip标识,Number类型转成BOOL类型
    23.         self.content = dict[@"content"];        // 微博正文
    24.         self.image = dict[@"image"];            // 微博配图图片名称
    25.     }
    26.     return self;
    27. }
    28. @end
    复制代码
    SAWeiboFrame.h
    1. //
    2. //  SAWeiboFrame.h
    3. //  Weibo
    4. //
    5. //  Created by yusian on 14-4-10.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import <Foundation/Foundation.h>
    9. #define kIconWH 40                                  // 头像宽高
    10. #define kInterval 10                                // 全局间距
    11. #define kVipWH  14                                  // vip标识宽高
    12. #define kImageWH 200                                // 微博配图宽高
    13. #define kNameFont [UIFont systemFontOfSize:14]      // 昵称字号大小
    14. #define kTimeFont [UIFont systemFontOfSize:12]      // 发表时间字号大小
    15. #define kSourceFont [UIFont systemFontOfSize:12]    // 微博来源字号大小
    16. #define kContentFont [UIFont systemFontOfSize:15]   // 微博正文字号大小
    17. @class SAWeibo;
    18. @interface SAWeiboFrame : NSObject
    19. @property (nonatomic, assign, readonly) CGRect  iconViewFrame;      // 头像尺寸位置
    20. @property (nonatomic, assign, readonly) CGRect  nameLabelFrame;     // 昵称尺寸位置
    21. @property (nonatomic, assign, readonly) CGRect  timeLabelFrame;     // 发表时间尺寸位置
    22. @property (nonatomic, assign, readonly) CGRect  vipViewFrame;       // vip标识尺寸位置
    23. @property (nonatomic, assign, readonly) CGRect  sourceLabelFrame;   // 微博来源尺寸位置
    24. @property (nonatomic, assign, readonly) CGRect  contentLabelFrame;  // 微博正文尺寸位置
    25. @property (nonatomic, assign, readonly) CGRect  imageViewFrame;     // 微博配图尺寸位置
    26. @property (nonatomic, assign, readonly) CGFloat cellHeight;         // 每条微博Cell高度
    27. @property (nonatomic, strong) SAWeibo *weibo;                       // 数据模型
    28. @end
    复制代码
    SAWeiboFrame.m
    1. //
    2. //  SAWeiboFrame.m
    3. //  Weibo
    4. //
    5. //  Created by yusian on 14-4-10.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import "SAWeiboFrame.h"
    9. #import "SAWeibo.h"
    10. @implementation SAWeiboFrame
    11. // 在数据模型set方法中将各子视图的尺寸大小及每条微博的行高进行计算与确定
    12. - (void)setWeibo:(SAWeibo *)weibo
    13. {
    14.     _weibo = weibo;     // 将创建好的模型对象赋值给成员变量,让模型数据成为视图框架模型的属性
    15.     // 1、头像
    16.     CGFloat iconX = kInterval;
    17.     CGFloat iconY = kInterval;
    18.     _iconViewFrame = CGRectMake(iconX, iconY, kIconWH, kIconWH);
    19.    
    20.     // 2、昵称
    21.     CGFloat nameX = CGRectGetMaxX(_iconViewFrame) + kInterval;
    22.     // CGRectGetMaxX(_iconViewFrame)为取头像Frame中X最大值
    23.    
    24.     CGFloat nameY = iconY;
    25.     CGSize nameSize = [_weibo.name sizeWithFont:kNameFont];
    26.     // [_weibo.name sizeWithFont:kNameFont]字符串方法,意为该字符串在某种字体状态下所占据的尺寸
    27.    
    28.     _nameLabelFrame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height);
    29.    
    30.     // 3、vip
    31.     CGFloat vipX = CGRectGetMaxX(_nameLabelFrame) + kInterval;
    32.     CGFloat vipY = iconY;
    33.     _vipViewFrame = CGRectMake(vipX, vipY, kVipWH, kVipWH);
    34.    
    35.     // 4、时间
    36.     CGFloat timeX = nameX;
    37.     CGFloat timeY = CGRectGetMaxY(_nameLabelFrame) + kInterval;
    38.     CGSize timeSize = [_weibo.time sizeWithFont:kTimeFont];
    39.     _timeLabelFrame = CGRectMake(timeX, timeY, timeSize.width, timeSize.height);
    40.    
    41.     // 5、来源
    42.     CGFloat sourceX = CGRectGetMaxX(_timeLabelFrame) + kInterval;
    43.     CGFloat sourceY = timeY;
    44.     NSString *sourceText = [NSString stringWithFormat:@"来自:%@", _weibo.source];
    45.     CGSize sourceSize = [sourceText sizeWithFont:kSourceFont];
    46.     // 计算尺寸应为实际显示内容的尺寸,所以取拼串后字符串的sizeWithFont:方法
    47.    
    48.     _sourceLabelFrame = CGRectMake(sourceX, sourceY, sourceSize.width, sourceSize.height);
    49.    
    50.     // 6、正文
    51.     CGFloat contentX = iconX;
    52.     CGFloat contentY = MAX(CGRectGetMaxY(_iconViewFrame), CGRectGetMaxY(_timeLabelFrame)) + kInterval;
    53.     // 正文与上面子视图保持一个全局间隔距离,但无法确定头像与发表时间哪个子视图下边缘Y值更大,所以利用宏MAX(A, B)对这两个子视图进行比较,以最大值为标准
    54.    
    55.     CGFloat contentWidth = 320 - 2 * kInterval;
    56.     // 正文宽度保持屏幕两侧预算一个全局间隔距离即可
    57.    
    58.     CGSize contentSize = [_weibo.content sizeWithFont:kContentFont constrainedToSize:CGSizeMake(contentWidth, MAXFLOAT)];
    59.     _contentLabelFrame = CGRectMake(contentX, contentY, contentSize.width, contentSize.height);
    60.    
    61.     // 7、配图
    62.     if (self.weibo.image) {
    63.         CGFloat imageX = contentX;
    64.         CGFloat imageY = CGRectGetMaxY(_contentLabelFrame) + kInterval;
    65.         _imageViewFrame = CGRectMake(imageX, imageY, kImageWH, kImageWH);
    66.         
    67.         // 如果有配图,则每条微博高度以配图下边缘Y值为基准
    68.         _cellHeight = CGRectGetMaxY(_imageViewFrame) + kInterval;
    69.     } else {
    70.         // 如果没有配置,则每条微博高度以正文下边缘Y值为基准
    71.         _cellHeight = CGRectGetMaxY(_contentLabelFrame) + kInterval;
    72.     }
    73.    
    74. }
    75. @end
    复制代码
    SAWeiboCell.h
    1. //
    2. //  SAWeiboCell.h
    3. //  Weibo
    4. //
    5. //  Created by yusian on 14-4-10.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import <UIKit/UIKit.h>
    9. @class SAWeiboFrame;
    10. @interface SAWeiboCell : UITableViewCell
    11. @property (nonatomic, strong) SAWeiboFrame *weiboFrame;     // 让视图框架模型成为Cell模型的属性
    12. + (NSString *)ID;       // 封装tableView的缓存cell标识
    13. @end
    复制代码
    SAWeiboCell.m
    1. //
    2. //  SAWeiboCell.m
    3. //  Weibo
    4. //
    5. //  Created by yusian on 14-4-10.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import "SAWeiboCell.h"
    9. #import "SAWeiboFrame.h"
    10. #import "SAWeibo.h"
    11. @interface SAWeiboCell ()   // 类扩展成员变量
    12. {
    13.     UIImageView     *_iconView;         // 头像
    14.     UIImageView     *_vipView;          // vip标识
    15.     UILabel         *_nameLabel;        // 昵称
    16.     UILabel         *_sourceLabel;      // 微博来源
    17.     UILabel         *_timeLabel;        // 发表时间
    18.     UILabel         *_contentLabel;     // 微博正文
    19.     UIImageView     *_imageView;        // 微博配图
    20. }
    21. @end
    22. @implementation SAWeiboCell
    23. #pragma mark cell初始化方法
    24. - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    25. {
    26.     if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
    27.         
    28.         // 1、头像
    29.         _iconView = [[UIImageView alloc] init];
    30.         [self.contentView addSubview:_iconView];
    31.         
    32.         // 2、昵称
    33.         _nameLabel = [[UILabel alloc] init];
    34.         _nameLabel.font = kNameFont;
    35.         [self.contentView addSubview:_nameLabel];
    36.         
    37.         // 3、vip标识
    38.         _vipView = [[UIImageView alloc] init];
    39.         _vipView.image = [UIImage imageNamed:@"vip.png"];
    40.         [self.contentView addSubview:_vipView];
    41.         
    42.         // 4、发表时间
    43.         _timeLabel = [[UILabel alloc] init];
    44.         _timeLabel.font = kTimeFont;
    45.         _timeLabel.textColor = [UIColor lightGrayColor];
    46.         [self.contentView addSubview:_timeLabel];
    47.         
    48.         // 5、微博来源
    49.         _sourceLabel = [[UILabel alloc] init];
    50.         _sourceLabel.font = kSourceFont;
    51.         _sourceLabel.textColor = [UIColor lightGrayColor];
    52.         [self.contentView addSubview:_sourceLabel];
    53.         
    54.         // 6、正文
    55.         _contentLabel = [[UILabel alloc] init];
    56.         _contentLabel.font = kContentFont;
    57.         [self.contentView addSubview:_contentLabel];
    58.         
    59.         // 7、配图
    60.         _imageView = [[UIImageView alloc] init];
    61.         [self.contentView addSubview:_imageView];
    62.         
    63.     }
    64.     return self;
    65. }
    66. #pragma mark 成员变量weiboFrame的set方法
    67. - (void)setWeiboFrame:(SAWeiboFrame *)weiboFrame
    68. {
    69.     _weiboFrame = weiboFrame;   // 将创建好的Frame对象赋值给成员变量
    70.     [self settingView];         // 设置子视图数据
    71.     [self settingFrame];        // 设置子视图尺寸及位置
    72. }
    73. // 调用微博数据模型设置每条微博中子视图数据内容
    74. - (void)settingView
    75. {
    76.     // 1、头像
    77.     _iconView.image = [UIImage imageNamed:_weiboFrame.weibo.icon];
    78.    
    79.     // 2、昵称
    80.     _nameLabel.text = _weiboFrame.weibo.name;
    81.     if (_weiboFrame.weibo.isVip) {
    82.         _nameLabel.textColor = [UIColor redColor];      // 带vip标识的用户昵称显示为红色
    83.     } else {
    84.         _nameLabel.textColor = [UIColor blackColor];    // 非vip用户昵称显示为黑色
    85.     }
    86.    
    87.     // 3、vip
    88.     _vipView.hidden = !_weiboFrame.weibo.isVip;
    89.     // 4、时间
    90.     _timeLabel.text = _weiboFrame.weibo.time;
    91.    
    92.     // 5、来源
    93.     _sourceLabel.text = [NSString stringWithFormat:@"来自:%@", _weiboFrame.weibo.source];
    94.    
    95.     // 6、正文
    96.     _contentLabel.text = _weiboFrame.weibo.content;
    97.     _contentLabel.numberOfLines = 0;                    // 多行文本
    98.    
    99.     // 7、配图
    100.     if (_weiboFrame.weibo.image) {
    101.         _imageView.hidden = NO;
    102.         _imageView.image = [UIImage imageNamed:_weiboFrame.weibo.image];
    103.         _imageView.contentMode = UIViewContentModeScaleAspectFit;
    104.         // 图片显示模式为最大化填充,非拉伸效果,不改变图片宽高比
    105.         
    106.     } else {
    107.         _imageView.hidden = YES;
    108.     }
    109. }
    110. // 调用子视图框架模型设置每条微博中子视图的尺寸及位置
    111. - (void)settingFrame
    112. {
    113.     // 1、头像
    114.     _iconView.frame = _weiboFrame.iconViewFrame;
    115.    
    116.     // 2、昵称
    117.     _nameLabel.frame = _weiboFrame.nameLabelFrame;
    118.    
    119.     // 3、vip
    120.     _vipView.frame = _weiboFrame.vipViewFrame;
    121.    
    122.     // 4、时间
    123.     _timeLabel.frame = _weiboFrame.timeLabelFrame;
    124.    
    125.     // 5、来源
    126.     _sourceLabel.frame = _weiboFrame.sourceLabelFrame;
    127.    
    128.     // 6、正文
    129.     _contentLabel.frame = _weiboFrame.contentLabelFrame;
    130.    
    131.     // 7、配图
    132.     _imageView.frame = _weiboFrame.imageViewFrame;
    133. }
    134. // 封装tableView缓存中重复利用Cell的标识
    135. +(NSString *)ID
    136. {
    137.     return @"Weibo";
    138. }
    139. @end
    复制代码
    SAWeiboController.h
    1. //
    2. //  SAWeiboController.h
    3. //  Weibo
    4. //
    5. //  Created by yusian on 14-4-10.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import <UIKit/UIKit.h>
    9. @interface SAWeiboController : UITableViewController
    10. @end
    复制代码
    SAWeiboController.m
    1. //
    2. //  SAWeiboController.m
    3. //  Weibo
    4. //
    5. //  Created by yusian on 14-4-10.
    6. //  Copyright (c) 2014年 yusian. All rights reserved.
    7. //
    8. #import "SAWeiboController.h"
    9. #import "SAWeibo.h"
    10. #import "SAWeiboFrame.h"
    11. #import "SAWeiboCell.h"
    12. @interface SAWeiboController ()
    13. {
    14.     NSMutableArray *_weiboFrames;       // 可变数据保存视图框架模型
    15. }
    16. @end
    17. @implementation SAWeiboController
    18. - (void)viewDidLoad
    19. {
    20.     [super viewDidLoad];
    21.     _weiboFrames = [NSMutableArray array];
    22.    
    23.     // 将plist文件读取到数据,原始数据
    24.     NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Weibo.plist" ofType:nil]];
    25.    
    26.     for (NSDictionary *dict in array) {
    27.         SAWeiboFrame *weiboFrame = [[SAWeiboFrame alloc] init]; // 创建视图框架模型
    28.         weiboFrame.weibo = [SAWeibo weiboWithDict:dict];        // 将原始数据转换成数据模型
    29.         [_weiboFrames addObject:weiboFrame];                    // 视图框架模型保存到数组
    30.     }
    31.    
    32.     // 利用tableView缓存数据机制中的一个特别处理方式,如果缓存中没有则调用相关类创建
    33.     [self.tableView registerClass:[SAWeiboCell class] forCellReuseIdentifier:[SAWeiboCell ID]];
    34.     /*等同于以下代码
    35.     if (cell == nil) {
    36.         cell = [[SAWeiboCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[SAWeiboCell ID]];
    37.     }*/
    38. }
    39. #pragma mark - Table view data source
    40. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    41. {
    42.     return _weiboFrames.count;
    43. }
    44. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    45. {
    46.     // 缓存中取相关对象重复利用
    47.     SAWeiboCell *cell = [tableView dequeueReusableCellWithIdentifier:[SAWeiboCell ID]];
    48.    
    49.     // 将数据视图框架模型(该模型中包含了数据模型)赋值给Cell,展示每条微博内容
    50.     cell.weiboFrame = _weiboFrames[indexPath.row];
    51.    
    52.     return cell;
    53. }
    54. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    55. {
    56.     // 调用视图框架模型返回每条微博动态高度
    57.     return [_weiboFrames[indexPath.row] cellHeight];
    58. }
    59. @end
    复制代码
    4、源代码下载
    游客,本帖隐藏的内容需要积分高于 1 才可浏览,您当前积分为 0

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

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

    GMT+8, 2024-4-27 14:54 , Processed in 0.062372 second(s), 26 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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