UITableViewCell之微博篇
微博篇
本应用所涉及的知识点:
- 1.UITableView 中的cell
- 2.模型的创建
- 3.MJExtension第三方框架的使用
需求分析
1.界面分析
微博界面
界面控件分析:
- 整个页面
- 1.不难知道,界面是由若干个子cell组成的,并且每个子cell的高度都不同,高度都是由内容来定.
- 2.子模块的控件数不一样,有的是有五个子控件,有的有四个子控件,而有的只有三个.
- 3.子控件的类型分别是:头像(UIImageView),昵称(UILabel),Vip(UIImageView),微博正文(UILabel)和配图(UIImageView).
- 各个子模块
- 1.子控件个数:每个模块的控件数都不一定一样,但是考虑到实现功能的时候能够快速方便的实现,所以在声明属性的时候,我们还是选择五个控件.
- 2.子控件的高度:由界面可知,整个子控件的高度只与图标,微博正文和配图(不一定有)有关.
- 3.在进行加载时,就需要先判断是否是Vip和是否有配图,然后再进行加载.
- 整个页面
2.功能分析
- 整体功能
- 用户能够根据自己的心情上传微博正文和配图,并能够在界面上浏览其他人的微博内容.
- 子控件功能
- 根据每个人的账户数据不同来展示头像,昵称和是否是会员,并加载微博正文和是否有配图.
- 整体功能
程序的实现
界面的实现
界面初实现
1.主控件ViewController
- 首先将h文件中的UIViewController改为UITableViewController
#import <UIKit/UIKit.h> @interface ViewController : UITableViewController @end
- 然后再在main.storyboard中设置
- 首先将h文件中的UIViewController改为UITableViewController
- 2.再创建分类,继承UITableViewCell,例如ZYQStatusCell
- 2.1UITableViewCell.h文件
#import <UIKit/UIKit.h> @class ZYQStatus; @interface ZYQStatusCell : UITableViewCell @end
- 2.2在UITableViewCell.m文件中重写initWithStyle方法创建各个子控件并添加到父控件contentSize中,并在layoutSubviews方法中设置各个子控件的位置.
#import "ZYQStatusCell.h"
@interface ZYQStatusCell () /** 图像*/ @property (nonatomic ,weak)UIImageView *iconImageView; /** 昵称*/ @property (nonatomic ,weak)UILabel *nameLabel; /** vip*/ @property (nonatomic ,weak)UIImageView *vipImageView; /** 正文*/ @property (nonatomic ,weak)UILabel *text_Label; /** 配图*/ @property (nonatomic ,weak)UIImageView *pictureImageView; @end @implementation ZYQStatusCell // 把有可能显示的子控件都添加进去 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { /** 图像*/ UIImageView *iconImageView = [[UIImageView alloc]init]; iconImageView.backgroundColor = [UIColor redColor]; [self.contentView addSubview:iconImageView]; self.iconImageView = iconImageView; /** 昵称*/ UILabel *nameLabel = [[UILabel alloc]init]; nameLabel.backgroundColor = [UIColor yellowColor]; [self.contentView addSubview:nameLabel]; self.nameLabel = nameLabel; /** vip*/ UIImageView *vipImageView = [[UIImageView alloc] init]; vipImageView.backgroundColor = [UIColor greenColor]; [self.contentView addSubview:vipImageView]; self.vipImageView = vipImageView; /** 配图*/ UIImageView *pictureImageView = [[UIImageView alloc] init]; pictureImageView.backgroundColor = [UIColor grayColor]; [self.contentView addSubview:pictureImageView]; self.pictureImageView = pictureImageView; /** 正文*/ UILabel *text_Label = [[UILabel alloc] init]; text_Label.backgroundColor = [UIColor blueColor]; [self.contentView addSubview:text_Label]; self.text_Label = text_Label; } return self; } //设置各控件的位置 - (void)layoutSubviews { [super layoutSubviews]; CGFloat space = 10; /** 图像*/ CGFloat iconX = space; CGFloat iconY = space; CGFloat iconWH = 40; self.iconImageView.frame = CGRectMake(iconX, iconY, iconWH, iconWH); /* 昵称*/ CGFloat nameX = CGRectGetMaxX(self.iconImageView.frame) + space; CGFloat nameY = iconY; CGFloat nameW = nameSize.width; CGFloat nameH = nameSize.height; self.nameLabel.frame = CGRectMake(nameX, nameY, nameW, nameH); /** vip*/ CGFloat vipW = 14; CGFloat vipH = nameH; CGFloat vipX = CGRectGetMaxX(self.nameLabel.frame) + space; CGFloat vipY = nameY; self.vipImageView.frame = CGRectMake(vipX, vipY, vipW, vipH); /** 正文*/ CGFloat textX = iconX; CGFloat textY = CGRectGetMaxY(self.iconImageView.frame) + space; CGFloat textW = self.contentView.frame.size.width - 2 * space; self.text_Label.frame = CGRectMake(textX, textY, textW, textH); // 配图 CGFloat pictureX = textX; CGFloat pictureY = CGRectGetMaxY(self.text_Label.frame) + space; CGFloat pictureWH = 100; self.pictureImageView.frame = CGRectMake(pictureX, pictureY, pictureWH, pictureWH); }
- 在主控件文件中,只需要实现相对应的代理方法
#import "ViewController.h"
#import "ZYQStatusCell.h"@interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.tableView.rowHeight = 250; } #pragma mark - 数据源方法 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 20; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [[UITableViewCell alloc]init]; return cell; } @end
- 运行结果:
功能的实现
数据内容的加载
- 为了能够使得程序能够更加简单,就需要创建模型,例如:ZYQStatus,此时就需要声明各个子控件的属性.
#import <Foundation/Foundation.h>
@interface ZYQStatus : NSObject /** 图像*/ @property(nonatomic, copy)NSString *icon; /** 昵称*/ @property(nonatomic, copy)NSString *name; /** 正文*/ @property(nonatomic, copy)NSString *text; /** vip*/ @property(nonatomic, assign,getter=isVip)BOOL vip; /** 配图*/ @property(nonatomic, copy)NSString *picture; @end
- 同时在UITableViewCell.h文件中,也需要声明一个微博模型
#import <UIKit/UIKit.h>@class ZYQStatus; @interface ZYQStatusCell : UITableViewCell /** 微博模型*/ @property(nonatomic, strong)ZYQStatus *status; @end
- 同时在UITableViewCell.m文件中,就需要重写微博模型的set方法
#import "ZYQStatusCell.h"
#import "ZYQStatus.h"#define ZYQTextFont [UIFont systemFontOfSize:14] #define ZYQNameFont [UIFont systemFontOfSize:17] @interface ZYQStatusCell () /** 图像*/ @property (nonatomic ,weak)UIImageView *iconImageView; /** 昵称*/ @property (nonatomic ,weak)UILabel *nameLabel; /** vip*/ @property (nonatomic ,weak)UIImageView *vipImageView; /** 正文*/ @property (nonatomic ,weak)UILabel *text_Label; /** 配图*/ @property (nonatomic ,weak)UIImageView *pictureImageView; @end @implementation ZYQStatusCell // 把有可能显示的子控件都添加进去 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { /** 图像*/ UIImageView *iconImageView = [[UIImageView alloc]init]; iconImageView.backgroundColor = [UIColor redColor]; [self.contentView addSubview:iconImageView]; self.iconImageView = iconImageView; /** 昵称*/ UILabel *nameLabel = [[UILabel alloc]init]; nameLabel.backgroundColor = [UIColor yellowColor]; nameLabel.font = ZYQNameFont; [self.contentView addSubview:nameLabel]; self.nameLabel = nameLabel; /** vip*/ UIImageView *vipImageView = [[UIImageView alloc] init]; vipImageView.contentMode = UIViewContentModeCenter; vipImageView.backgroundColor = [UIColor greenColor]; vipImageView.image = [UIImage imageNamed:@"vip"]; [self.contentView addSubview:vipImageView]; self.vipImageView = vipImageView; /** 配图*/ UIImageView *pictureImageView = [[UIImageView alloc] init]; pictureImageView.backgroundColor = [UIColor grayColor]; [self.contentView addSubview:pictureImageView]; self.pictureImageView = pictureImageView; /** 正文*/ UILabel *text_Label = [[UILabel alloc] init]; text_Label.backgroundColor = [UIColor blueColor]; text_Label.font = ZYQTextFont; text_Label.numberOfLines = 0; [self.contentView addSubview:text_Label]; self.text_Label = text_Label; } return self; } //设置各控件的位置 - (void)layoutSubviews { [super layoutSubviews]; CGFloat space = 10; /** 图像*/ CGFloat iconX = space; CGFloat iconY = space; CGFloat iconWH = 40; self.iconImageView.frame = CGRectMake(iconX, iconY, iconWH, iconWH); /* 昵称*/ CGFloat nameX = CGRectGetMaxX(self.iconImageView.frame) + space; CGFloat nameY = iconY; // 计算昵称文字的尺寸 NSDictionary *nameAtt = @{NSFontAttributeName : ZYQNameFont}; CGSize nameSize = [self.status.name sizeWithAttributes:nameAtt]; CGFloat nameW = nameSize.width; CGFloat nameH = nameSize.height; self.nameLabel.frame = CGRectMake(nameX, nameY, nameW, nameH); /** vip*/ if (self.status.isVip) { CGFloat vipW = 14; CGFloat vipH = nameH; CGFloat vipX = CGRectGetMaxX(self.nameLabel.frame) + space; CGFloat vipY = nameY; self.vipImageView.frame = CGRectMake(vipX, vipY, vipW, vipH); } /** 正文*/ CGFloat textX = iconX; CGFloat textY = CGRectGetMaxY(self.iconImageView.frame) + space; CGFloat textW = self.contentView.frame.size.width - 2 * space; NSDictionary *textArr = @{NSFontAttributeName : ZYQTextFont}; CGSize textMaxSize = CGSizeMake(textW, MAXFLOAT); CGFloat textH = [self.status.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:textArr context:nil].size.height; self.text_Label.frame = CGRectMake(textX, textY, textW, textH); if (self.status.picture) { // 有配图 CGFloat pictureX = textX; CGFloat pictureY = CGRectGetMaxY(self.text_Label.frame) + space; CGFloat pictureWH = 100; self.pictureImageView.frame = CGRectMake(pictureX, pictureY, pictureWH, pictureWH); } } //重写status的set方法 - (void)setStatus:(ZYQStatus *)status { _status = status; //设置头像 self.iconImageView.image = [UIImage imageNamed:status.icon]; //设置昵称 self.nameLabel.text = status.name; //设置是否vip if (status.isVip) { self.vipImageView.hidden = NO; self.nameLabel.textColor = [UIColor orangeColor]; } else { self.vipImageView.hidden = YES; self.nameLabel.textColor = [UIColor blackColor]; } //设置正文 self.text_Label.text = status.text; //设置配图 if (status.picture) { self.pictureImageView.hidden = NO; self.pictureImageView.image = [UIImage imageNamed:status.picture]; } else { self.pictureImageView.hidden = YES; } } @end
- 在主控件文件中,只需要实现相对应的代理方法.在加载数据时,为了更好地将字典转换成模型,我们就使用了MJExtension框架.
#import "ViewController.h"
#import "ZYQStatus.h"
#import "ZYQStatusCell.h" #import "MJExtension.h" @interface ViewController () //所有微博数据 @property(nonatomic,strong)NSArray *statuses; @end @implementation ViewController //懒加载 - (NSArray *)statuses { if (!_statuses) { _statuses = [ZYQStatus mj_objectArrayWithFilename:@"statuses.plist"]; } return _statuses; } NSString *ID = @"status"; - (void)viewDidLoad { [super viewDidLoad]; //注册cell [self.tableView registerClass:[ZYQStatusCell class] forCellReuseIdentifier:ID]; self.tableView.rowHeight = 250; } #pragma mark - 数据源方法 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.statuses.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //访问缓存池 ZYQStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; //设置数据 cell.status = self.statuses[indexPath.row]; return cell; } @end
- 运行结果:
- 结果分析:
- 整体界面实现了功能,但是还有明显的不足,就是高度是固定的,所以就得进行优化,动态计算高度.
- 由于在加载子控件的时候,先计算出cell的高度后才会加载子控件,所以在加载子控件之前就得计算好高度.
- 解决方案:在这个方法返回之前计算好cell的高度
// 方案:在这个方法返回之前计算好cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ZYQStatus *status = self.statuses[indexPath.row]; CGFloat space = 10; /** 图像*/ CGFloat iconX = space; CGFloat iconY = space; CGFloat iconWH = 40; CGRect iconImageViewFrame = CGRectMake(iconX, iconY, iconWH, iconWH); /** 正文*/ CGFloat textX = iconX; CGFloat textY = CGRectGetMaxY(iconImageViewFrame) + space; CGFloat textW = [UIScreen mainScreen].bounds.size.width - 2 * space; NSDictionary *textArr = @{NSFontAttributeName : [UIFont systemFontOfSize:14]}; CGSize textMaxSize = CGSizeMake(textW, MAXFLOAT); CGFloat textH = [status.text boundingRectWithSize:textMaxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:textArr context:nil].size.height; CGRect text_LabelFrame = CGRectMake(textX, textY, textW, textH); CGFloat cellH = 0; if (status.picture) { // 有配图 CGFloat pictureX = textX; CGFloat pictureY = CGRectGetMaxY(text_LabelFrame) + space; CGFloat pictureWH = 100; CGRect pictureImageViewFrame = CGRectMake(pictureX, pictureY, pictureWH, pictureWH); cellH = CGRectGetMaxY(pictureImageViewFrame) + space; } else { cellH = CGRectGetMaxY(text_LabelFrame) + space; } return cellH; }
- 另外:在viewDidLoad中就不需要给每一行cell的高度赋值.
- (void)viewDidLoad {[super viewDidLoad];//注册cell[self.tableView registerClass:[ZYQStatusCell class] forCellReuseIdentifier:ID]; }
- 运行结果:
总结:
难点
- 难点之一:动态计算每一个cell的高度.
- 难点之二:在加载子控件的时候,有的需要先进行判断在决定是否添加.
注意点
- 注意点1:在main.storyboard中,需要将UITableViewController的class设置为ViewController,并设置为程序加载启动界面.
- 注意点2:在计算昵称的高度时,需要在创建nameLabel控件时指定字体类型,同时在layoutSubViews方法计算高度时,也需要指定同种类型.
- 注意点3:在计算微博正文的高度时,需要在创建TextLabel控件的时候,指定字体类型,同时还得指定最大宽度.
转载于:https://www.cnblogs.com/zhoudaquan/p/4996204.html
UITableViewCell之微博篇相关推荐
- 一个自动化测试的案例之记事狗微博篇
一个自动化测试的案例之记事狗微博篇 前言: 针对于我这个学计算机的孩子,总是希望能够增强动手能力,在机子小小感冒时,能够自己帮它治愈,但现实情况是我总是把它搞成重病患者,貌似每次的动手能力,都让我的机 ...
- 那些年送出去的交互方案-微博篇
对于交互设计师,很多公司招人都要出个方案,你懂得,已无力.遂结合自己的交互工作经验,同时也作为一个归档将一些感兴趣的产品进行部分的归纳总结,希望能把我的思考分享出来. 动效若不能观看,可以戳这里 ht ...
- Python扫码登录保存和验证cookies值——微博篇(五)
python实现扫码登录微博网页版 一.找到生成二维码链接地址 二.找到确认二维码链接地址 三.继续寻找相关链接地址获取登录信息 四.最后保存cookies值并进行验证是否有效或登录状态 完整代码 五 ...
- 【Python爬虫实例学习篇】——5、【超详细记录】从爬取微博评论数据(免登陆)到生成词云
[Python爬虫实例学习篇]--5.[超详细记录]从爬取微博评论数据(免登陆)到生成词云 个人博客地址:ht/tps://www.asyu17.cn/ 精彩部分提醒: (1)微博评论页详情链接为一个 ...
- Python扫码登录保存和验证cookies值——网易云音乐篇(九)
python实现扫码登录网易云音乐网页版 一.打开二维码扫码登录页面,找到二维码图片链接 二.破解获取params和encSecKey值 注意:from Crypto.Cipher import AE ...
- Android 11 微信,QQ ,微博 分享适配
Android 11 微信,QQ ,微博 分享适配 前言 微信篇 QQ篇 微博篇 前言 最近收到客服反馈 有用户反馈微信分享不了,具体询问一番发现是Android 11的小米机器,然后依次试了 QQ ...
- Python扫码登录保存和验证cookies值——快手篇(二)
python实现扫码登录快手网页版 一.找到生成登录二维码地址获取参数 二.找到第二个确认链接地址 三.最后保存cookies值并进行验证 完整代码 四.更多文章 一.找到生成登录二维码地址获取参数 ...
- 微博与中国版SNS的未来
从今年3月底至现在,新浪微博放出了两个标志性的信号:1)新浪使用自有搜索引擎技术替代谷歌搜索:2)新浪微博启用weibo.com域名.这两个动作表面看起来毫无直接瓜葛,但从本质看来,搜索会变成微博在未 ...
- Python扫码登录保存和验证cookies值——微信公众号篇(四)
python实现扫码登录微信公众号 一.通过研究观察找到相关链接地址 二.通过上面两个值再运行访问二维码链接地址 三.找到扫码后确认链接地址 四.找到最后访问链接地址获取真正登录信息 五.最后保存co ...
最新文章
- 不要用JWT替代session管理(上):全面了解Token,JWT,OAuth,SAML,SSO
- Typora 快捷键
- 使用Windows10 software center升级版本1909
- .NET Core 2.1中的HttpClientFactory最佳实践
- [转]本地图片预览二三事
- 避免大规模故障的微服务架构
- C# 导入word word导入
- Java NIO 和 IO的区别
- VSCode : vscode-remote下无法写入文件及linux文件读写权限
- 教你如何用Python轻轻松松操作Excel、Word、CSV,一文就够了,赶紧码住!!!
- 必读开发规范之阿里巴巴开发手册(个人整理版)
- 帝国军师--约森·梅尔沃德(微软技术总监)
- ubuntu修改开机密码
- Android6.0动态获取权限java.io.FileNotFoundException: …Permission denied
- base64编码解码器【C++】
- 城南花未开,老程已不在;
- 台湾南海岸一带发生了7.1级地震
- qt中c语言函数发送qt信号,关于c ++:从Qt中的静态类方法发送信号
- python 月日年转年月日_在Python中将年/月/日转换为年份
- 德国变态驱蚊水,喷一次驱蚊12小时!打开门窗都能安心睡觉,比花露水好用10086倍...
热门文章
- 程序员去哪里找国外朋友来进行学习英语?
- 从 回调地狱 到神奇的 promise
- The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz‘ failed with error: Get “http://loc
- javascript+CSS3 3D游戏/效果
- 介绍信贷产品进件要求及系统录入规范
- 谷歌浏览器缓存无法清除?
- TCP长连接下,在应用层面,定制自己的负载均衡
- centOS 安装VScode
- 达摩院成立XG实验室,阿里官宣进军5G
- 机械制造工艺学课程设计——发动机连杆加工(说明书+CATIA三维模型+CAD图纸+工序卡+过程卡)