代码地址如下:
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. 详解ListView加载网络图片的优化,让你轻松掌握!

    详解ListView加载网络图片的优化,让你轻松掌握! 写博客辛苦了,转载的朋友请标明出处哦,finddreams(http://blog.csdn.net/finddreams/article/de ...

  2. 【转】如何只用CSS做到完全居中

    英文原版链接:http://codepen.io/shshaw/full/gEiDt 我们都知道 margin:0 auto; 的样式能让元素水平居中,而 margin: auto; 却不能做到垂直居 ...

  3. Centos7重置root密码的方法(亲测有效)

    CentOS 7的更新还是非常大的,很多平时使用的命令已经变化了,要上手还真要一段时间.比如忘记root密码.在5.6的系统中直接进入单用户模式下,一个passwd命令修改,重启即可.但是在Cento ...

  4. mysql 保留点

    例子如下: 在ticket表中先删除trainID=868的数据,设置一个保留点,然后插入一行数据,发现在插入数据插错了,这个时候我们的保留点就可以排上用场了,即rollback到保留点,而不是直接r ...

  5. keyPoints的相关函数

    cout<<"坐标:"<<keypoints1[i].pt; cout<<",邻域直径:"<<keypoints ...

  6. create table select from

    CREATE TABLE new_table AS SELECT * FROM old_table

  7. FFT&NTT&多项式相关

    打了FFT 感觉以后多项式不虚了 ~滑稽~ PS 关于详见没写完.... code #include<cmath> #include<cstdio> #include<c ...

  8. POJ 3608 Bridge Across Islands (旋转卡壳)

    [题目链接] http://poj.org/problem?id=3608 [题目大意] 求出两个凸包之间的最短距离 [题解] 我们先找到一个凸包的上顶点和一个凸包的下定点,以这两个点为起点向下一个点 ...

  9. 【贪心】Gym - 100507H - Pair: normal and paranormal

    每次取相邻的两个可以射击的从序列中删除,重复n次. 可以看作括号序列的匹配. #include<cstdio> #include<vector> using namespace ...

  10. jdk_配置

    如果不知道jdk安装目录,可以使用如下命令查找到jdk安装目录 linux /usr/libexec/java_home windows版 新建系统变量JAVA_HOME(自己jdk的安装目录)C:\ ...