代码地址如下:
http://www.demodashi.com/demo/11639.html

前言

学习过UITableView、AutoLayout以及MVC的相关知识,接下来通过一个微博页面实战来整合一下。

效果图

首先看一下效果图:

程序实现

需求分析

此页面为非等高cell,tableview的组数为1

cell内容根据数据动态展示

cell自适应高度,根据微博有无图片,适配自己高度

项目准备

数据均为本地数据(status.plist 和 images)

上手操作

1、创建工程、导入资源

2、创建MVC对应文件,本案例为:XYStatusesViewController、XYStatus、XYStatusCell控制器逻辑:
3、控制器只需管理逻辑.至于cell的创建和内部细节,全部封装起来

懒加载本地plist数据

- (NSMutableArray *)status {
if (_status == nil) { NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil];
NSArray *array = [NSArray arrayWithContentsOfFile:path]; NSMutableArray *arrayM = [NSMutableArray new];
for (NSDictionary *dict in array) { XYStatus *status = [XYStatus statusWithDict:dict]; [arrayM addObject:status]; } _status = arrayM; }
return _status;
}

返回tableView对应的数据源

#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.status.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { XYStatusCell *cell = [XYStatusCell cellWithTableView:tableView]; cell.status = self.status[indexPath.row]; NSLog(@"cell.height = %zd",cell.height); return cell;
}
/**
* 不知是Xcode8的特性还是iOS10 特性。所以这种通过model保存高度的方法,可以不用写估算方法也行。
* 因为最初精算,返回值为0,Model中没有保存。然后返回cell之后,再精算的时候返回真实的保存值。
*/
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"-----heightForRowAtIndexPath------");
XYStatus *status = self.status[indexPath.row];
return status.cellHeight; }
/**
* 这个方法很重要:是估算cell的高度。有这个方法的调用顺序是: 1.估算 2.返回cell 3. 计算准确高度
* 否则:1.计算准确高度 2.返回cell 3.再计算准确高度
*
* 不知是Xcode8的特性还是iOS10 特性。所以这种通过model保存高度的方法,可以不用写估算方法也行
*/
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{ NSLog(@"-----estimatedHeightForRowAtIndexPath------"); return 200;
}

模型的封装:模型用来存储内部数据、并通过KVC来保存传入数据

@property (nonatomic, copy) NSString *text;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *picture;
@property (nonatomic, assign,getter=isVip) BOOL vip;
/**
* cellHeight
*/
@property (nonatomic, assign) CGFloat cellHeight;
+ (instancetype)statusWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;
// 内部实现
+ (instancetype)statusWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self == [super init]) { [self setValuesForKeysWithDictionary:dict]; }
return self;
}

View的封装,cell推荐使用xib创建,因为方便

首先cell需要一个status属性、并提供一个类方法创建实例

@property (nonatomic, strong) XYStatus *status;
+ (instancetype)cellWithTableView:(UITableView *)tableView;

在Xib中设置内容控件并拖到.m中(设置好复用标识)

根据Xib创建view的步骤来,设置cell

cell类方法的实现

+ (instancetype)cellWithTableView:(UITableView *)tableView
{ static NSString *ID = @"cell";
XYStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (cell == nil) {
cell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject]; } return cell;
}

设置cell的数据 status

- (void)setStatus:(XYStatus *)status
{
_status = status; self.iconView.image = [UIImage imageNamed:status.icon]; self.nameLabel.text = status.name; self.contentLabel.text = status.text; if (status.isVip) { self.vipView.hidden = NO;
self.vipView.image = [UIImage imageNamed:@"vip"];
self.nameLabel.textColor = [UIColor orangeColor];
}else
{
self.vipView.hidden = YES;
self.nameLabel.textColor = [UIColor blackColor];
} if (status.picture) {
self.pictureView.hidden = NO;
self.pictureView.image = [UIImage imageNamed:status.picture]; _height = CGRectGetMaxY(self.pictureView.frame) + 10;
}else
{
self.pictureView.hidden = YES; _height = CGRectGetMaxY(self.contentLabel.frame) + 10;
} // 强制布局
[self layoutIfNeeded]; // 计算并标记高度保存到model中去
if (self.pictureView.hidden) {
_height = CGRectGetMaxY(self.contentLabel.frame) + 10;
}else
{
_height = CGRectGetMaxY(self.pictureView.frame) + 10;
} // 这里有个注意点:
// 通过强制布局使得cell子控件设置数据,计算出具体frame。
// 通过计算的cell的高度,来重新保存到status模型中
// 这里是C语言中指针的知识,如果有问题,欢迎留言
status.cellHeight = _height; }

项目代码结构截图

源码截图如下

小结:

麻雀虽小,五脏俱全。非等高cell实战--实现微博页面

代码地址如下:
http://www.demodashi.com/demo/11639.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

非等高cell实战--实现微博页面的更多相关文章

  1. 非等高cell实战(01)-- 实现微博页面

    非等高cell实战(01)-- 实现微博页面 学习过UITableView.AutoLayout以及MVC的相关知识,接下来通过一个微博页面实战来整合一下. 首先看一下效果图: 需求分析 此页面为非等 ...

  2. 自定义非等高 Cell

    1.自定义非等高 Cell介绍 1.1 代码自定义(frame) 新建一个继承自 UITableViewCell 的类. 重写 initWithStyle:reuseIdentifier: 方法. 添 ...

  3. iOS开发——UI进阶篇(三)自定义不等高cell,如何拿到cell的行高,自动计算cell高度,(有配图,无配图)微博案例

    一.纯代码自定义不等高cell 废话不多说,直接来看下面这个例子先来看下微博的最终效果 首先创建一个继承UITableViewController的控制器@interface ViewControll ...

  4. iOS边练边学--自定义非等高的cell

    一.使用xib或者storyboard自定义非等高的cell实现方式差不多,这里简单介绍一下通过xib文件实现的方法 <1.1>创建一个继承自UITableViewCell的子类,比如Ch ...

  5. Netty Redis 亿级流量 高并发 实战 (长文 修正版)

    目录 疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -30[ 博客园 总入口 ] 写在前面 1.1. 快速的能力提升,巨大的应用价值 1.1.1. 飞速提升能力,并且满足实际开发要求 1 ...

  6. 《Netty Zookeeper Redis 高并发实战》 图书简介

    <Netty Zookeeper Redis 高并发实战> 图书简介 本书为 高并发社群 -- 疯狂创客圈 倾力编著, 高度剖析底层原理,深度解读面试难题 疯狂创客圈 Java 高并发[ ...

  7. java高并发实战Netty+协程(Fiber)|系列1|事件驱动模式和零拷贝

    今天开始写一些高并发实战系列. 本系列主要讲两大主流框架: Netty和Quasar(java纤程库) 先介绍netty吧,netty是业界比较成熟的高性能异步NIO框架. 简单来说,它就是对NIO2 ...

  8. LVS集群和Keepalived高可用实战

    第四十章LVS集群和Keepalived高可用实战 一.ARP协议 1.概念 地址解析协议,即ARP(AddressResolutionProtocol),是根据IP地址获取物理MAC地址的一个TCP ...

  9. 自定义不等高cell—storyBoard或xib自定义不等高cell

    1.iOS8之后利用storyBoard或者xib自定义不等高cell: 对比自定义等高cell,需要几个额外的步骤(iOS8开始才支持) 添加子控件和contentView(cell的content ...

随机推荐

  1. Nginx-Primary script unknown的报错的解决方法

    配置nginx时一直报错:file not found 错误日志: [error] 12691#0: *6 FastCGI sent in stderr: "Primary script u ...

  2. python 根据文件创建时间排序

    #coding:utf8 import os,time directory = "d:/scrapy tutorial/" t = [] d = {} for filename i ...

  3. 7/26 CSU-ACM2018暑期训练3-递归&递推-选讲

    题目链接 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. Input 第一行是测试数据的数目t(0 <= ...

  4. 循环节(BFS)

    循环节 时间限制: 1 Sec  内存限制: 64 MB提交: 56  解决: 16[提交][状态][讨论版] 题目描述 第一节是英语课.今天,老师又教了桐桐很多单词.桐桐发现所有单词都有循环节(大写 ...

  5. 【AC自动机/fail树】BZOJ3172- [Tjoi2013]单词

    [题目大意] http://www.lydsy.com:808/JudgeOnline/problem.php?id=3172 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多 ...

  6. SVN 文件删除及恢复

    SVN 文件删除及恢复 在TortoiseSVN管理的项目中删除文件的方法:   1. 在客户端按delete删除(OS中删除,不通过SVN)           ● 未提交之前一旦Update则被删 ...

  7. Debian、Ubuntu 源列表说明

    转载:http://forum.ubuntu.org.cn/viewtopic.php?t=366506 概貌: 源列表主文件为 /etc/apt/sources.list,另兼取 /etc/apt/ ...

  8. mormot 直接使用UNIDAC引擎操作数据库

    mormot 直接使用UNIDAC引擎操作数据库 MORMOT封装了BDE.FIREDAC.UNIDAC.Nexus 四种通用型数据库引擎,形成了自己独特的数据引擎控件.前提条件是首先要安装通用型数据 ...

  9. 【k8s】了解一下k8s

    了解一下k8s 地址: https://www.kubernetes.org.cn/doc-11

  10. js循环遍历的两种方法for循环和for ... in 循环

    JS数组的遍历方法有两种: 第一种:一般的for循环,例如: var a = new Array("first", "second", "third& ...