微博篇

本应用所涉及的知识点:

  • 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中设置
  • 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之微博篇相关推荐

  1. 一个自动化测试的案例之记事狗微博篇

    一个自动化测试的案例之记事狗微博篇 前言: 针对于我这个学计算机的孩子,总是希望能够增强动手能力,在机子小小感冒时,能够自己帮它治愈,但现实情况是我总是把它搞成重病患者,貌似每次的动手能力,都让我的机 ...

  2. 那些年送出去的交互方案-微博篇

    对于交互设计师,很多公司招人都要出个方案,你懂得,已无力.遂结合自己的交互工作经验,同时也作为一个归档将一些感兴趣的产品进行部分的归纳总结,希望能把我的思考分享出来. 动效若不能观看,可以戳这里 ht ...

  3. Python扫码登录保存和验证cookies值——微博篇(五)

    python实现扫码登录微博网页版 一.找到生成二维码链接地址 二.找到确认二维码链接地址 三.继续寻找相关链接地址获取登录信息 四.最后保存cookies值并进行验证是否有效或登录状态 完整代码 五 ...

  4. 【Python爬虫实例学习篇】——5、【超详细记录】从爬取微博评论数据(免登陆)到生成词云

    [Python爬虫实例学习篇]--5.[超详细记录]从爬取微博评论数据(免登陆)到生成词云 个人博客地址:ht/tps://www.asyu17.cn/ 精彩部分提醒: (1)微博评论页详情链接为一个 ...

  5. Python扫码登录保存和验证cookies值——网易云音乐篇(九)

    python实现扫码登录网易云音乐网页版 一.打开二维码扫码登录页面,找到二维码图片链接 二.破解获取params和encSecKey值 注意:from Crypto.Cipher import AE ...

  6. Android 11 微信,QQ ,微博 分享适配

    Android 11 微信,QQ ,微博 分享适配 前言 微信篇 QQ篇 微博篇 前言 最近收到客服反馈 有用户反馈微信分享不了,具体询问一番发现是Android 11的小米机器,然后依次试了 QQ ...

  7. Python扫码登录保存和验证cookies值——快手篇(二)

    python实现扫码登录快手网页版 一.找到生成登录二维码地址获取参数 二.找到第二个确认链接地址 三.最后保存cookies值并进行验证 完整代码 四.更多文章 一.找到生成登录二维码地址获取参数 ...

  8. 微博与中国版SNS的未来

    从今年3月底至现在,新浪微博放出了两个标志性的信号:1)新浪使用自有搜索引擎技术替代谷歌搜索:2)新浪微博启用weibo.com域名.这两个动作表面看起来毫无直接瓜葛,但从本质看来,搜索会变成微博在未 ...

  9. Python扫码登录保存和验证cookies值——微信公众号篇(四)

    python实现扫码登录微信公众号 一.通过研究观察找到相关链接地址 二.通过上面两个值再运行访问二维码链接地址 三.找到扫码后确认链接地址 四.找到最后访问链接地址获取真正登录信息 五.最后保存co ...

最新文章

  1. 不要用JWT替代session管理(上):全面了解Token,JWT,OAuth,SAML,SSO
  2. Typora 快捷键
  3. 使用Windows10 software center升级版本1909
  4. .NET Core 2.1中的HttpClientFactory最佳实践
  5. [转]本地图片预览二三事
  6. 避免大规模故障的微服务架构
  7. C# 导入word word导入
  8. Java NIO 和 IO的区别
  9. VSCode : vscode-remote下无法写入文件及linux文件读写权限
  10. 教你如何用Python轻轻松松操作Excel、Word、CSV,一文就够了,赶紧码住!!!
  11. 必读开发规范之阿里巴巴开发手册(个人整理版)
  12. 帝国军师--约森·梅尔沃德(微软技术总监)
  13. ubuntu修改开机密码
  14. Android6.0动态获取权限java.io.FileNotFoundException: …Permission denied
  15. base64编码解码器【C++】
  16. 城南花未开,老程已不在;
  17. 台湾南海岸一带发生了7.1级地震
  18. qt中c语言函数发送qt信号,关于c ++:从Qt中的静态类方法发送信号
  19. python 月日年转年月日_在Python中将年/月/日转换为年份
  20. 德国变态驱蚊水,喷一次驱蚊12小时!打开门窗都能安心睡觉,比花露水好用10086倍...

热门文章

  1. 程序员去哪里找国外朋友来进行学习英语?
  2. 从 回调地狱 到神奇的 promise
  3. The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz‘ failed with error: Get “http://loc
  4. javascript+CSS3 3D游戏/效果
  5. 介绍信贷产品进件要求及系统录入规范
  6. 谷歌浏览器缓存无法清除?
  7. TCP长连接下,在应用层面,定制自己的负载均衡
  8. centOS 安装VScode
  9. 达摩院成立XG实验室,阿里官宣进军5G
  10. 机械制造工艺学课程设计——发动机连杆加工(说明书+CATIA三维模型+CAD图纸+工序卡+过程卡)