一.搭建界面
1.分析界面 需要使用什么控制器来管理
我们根据需求 可以用一个UITableViewController来管理
2.分析需求,我们发现cell的样式是固定的 系统的cell不能满足我们的需求
我们需要自定义cell 创建cell类,同时创建xib
3.如何加载xib文件
3.1 可以提供一个类方法快速创建
+ (instancetype)cell
{return[[[NSBundlemainBundle]loadNibNamed:@"XMGSubTagCell"owner:niloptions:nil]firstObject]; }
通过NSBundle加载xib描述cell,一定要记得绑定标示符, 而且在创建cell的时候 还要判断是否为空
XTSubTagCell*cell = [tableViewdequeueReusableCellWithIdentifier:ID];
if(cell ==nil) {
cell = [XTSubTagCellcell];
}
3.2 可以通过注册的方式 可以不用绑定标识符,也可以不做判断是否为空
二.加载数据
1.查看接口文档(基本url,请求参数,请求方式)
2.验证接口能否请求成功,查看服务器返回的数据 为什么?
(接口文档有可能描述错误,要自己去验证一下)
3.发送AFN请求
3.1 创建管理者对象
3.2 设置请求参数
3.3 发送请求
4.解析数据(写成pilst文件 分析数据)
5.设计模型,字典转模型
6.把模型展示到界面
怎么做?
6.1 在cell里面定义模型属性来接收模型数据
6.2 在cell里面定义要接收数据的属性
6.3 重写模型属性的set方法
6.4 给需要接收数据的参数赋值
7.设置完成 运行项目,发现tableView还是没有数据? 为什么
因为tableView只在启动的时候调用了一次数据源方法,这个时候还没有数据 设置完数据没有调用数据源方法
什么时候会重新调用数据源方法?
1 tableView第一次被加载的时候
2 刷新tableView表格
解决: 加载完数据之后(发送网络成功),刷新tableView表格 就会重新调用数据源方法
[self.tableViewreloadData];
三.cell内部结构处理
1.订阅数字处理
1.1 为什么要处理订阅数字?
订阅数非常大的时候,1万以上,我们希望显示为:XX万人订阅
2.2 在哪里处理?
我们在cell里面赋值的时候可以拿到订阅数 可以在cell内部做处理
2.3 怎么处理?
拿到订阅数(String类型),转换成CGFloat类型 显示为XX人订阅
CGFloatnumF = item.sub_number.floatValue;
判断一下不超过1万 直接显示, 超过一万 订阅数 /1万 保留一位小数 显示为XX万人订阅
2.4 如果正好是1万的整数倍 那么处理后的数据为XX.0万人 我们希望 .0 不要显示 怎么处理?
可以利用字符串替换
// 以后字符串不想要,就替换为空
numStr = [numStrstringByReplacingOccurrencesOfString:@".0"withString:@""];
2.头像圆角处理
2.1 怎么处理?
有三种处理方式设置圆角半径 图片裁剪 运行时
2.11 图片裁剪 怎么做? 在哪里写代码?
0.在cell里面赋值的时候可以拿到图片 可以在cell内部做处理
1.开启图形上下文
// UIGraphicsBeginImageContextWithOptions:绘制图片不清晰
// scale:比例因子 像素与点比例 0:自动识别
UIGraphicsBeginImageContextWithOptions(image.size,NO,0);
2.设置圆形裁剪区域
UIBezierPath*path = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0, image.size.width, image.size.height)];
3.超出裁剪区域剪切掉
[pathaddClip];
4.绘图
[imagedrawAtPoint:CGPointZero];
5. 获取图片
image =UIGraphicsGetImageFromCurrentImageContext();
6.关闭图形上下文
UIGraphicsEndImageContext();
2.12 设置圆角半径 在哪里写代码?
因为cell从xib加载,一定会调用awakeFromNib
// 当对象从xib加载完成就会调用
// 只会调用一次
- (void)awakeFromNib
{
// self.iconView.layer.cornerRadius = self.iconView.frame.size.width * 0.5;
// // 超出主层边框,就会裁剪掉
// self.iconView.layer.masksToBounds = YES;不设置的话, 看到的图片还是原来的形状(正方形)
}
2.13 运行时
在xib里面 选中要设置圆角的图片的imageView
3.分割线处理
3.1 为什么要处理分割线
系统的分割线没有占据整个cell 离cell得左边有一段距离 我们希望分割线占据整个cell
3.2 怎么处理?
1.自定义分割线
2.设置系统属性,让分割线占据全屏(iOS6和iOS7,iOS7和iOS8)
首先 我们要知道 分割线属于tableView的内容
在tableView里面搜IOS7 可以查看到IOS7版本新出来的API
我们找到一个内边距 尝试设置一下
// 取消分割线内边距
self.tableView.separatorInset=UIEdgeInsetsZero;
设置完之后我们发现分割线确实往左边移了一点,但还是没占据整个cell(ios8或以上的用户会有这个问题 ios7或一下的没有)
我们知道IOS8之后 出了一个layOut的内边距,整个属性属于UIView
我们去UIView里面去搜索IOS8新出的API 搜索到layoutMargins
// 取消约束边缘
self.tableView.layoutMargins=UIEdgeInsetsZero;
设置完之后我们发现没有效果 ,为什么?
可能是我们设置的对象搞错了,我们尝试一下给cell设置一下
cell.layoutMargins=UIEdgeInsetsZero;
设置完之后,我们发现就可以了 问题解决了
layoutMargins是IOS8de内容 我们项目设置的支持的最低版本为ios7,那么ios7用户使用ios8的api会报错
怎么解决?
判断一下 ios8以上的就不执行这个方法
怎么拿到当前手机版本
#define XTSystemVersion ([UIDevice currentDevice].systemVersion.floatValue)
if(XTSystemVersion>=8.0) {// 8.0以上才需要调用方法
cell.layoutMargins=UIEdgeInsetsZero;
}
3.setFrame重写cell的setFrame 1.取消系统分割线 2.设置tableView背景色为分割线颜色
优点:不用做屏幕适配 任何地方都能使用
设置cell的分割线,那么应该是设置cell的frame 在cell类里面写代码
怎么写?
0 取消系统的分割线
1 先设置tableView的背景颜色 想让分割线为什么颜色就设置背景色为什么颜色
2 只需要设置frame的高度比cell的高度小一点就可以了
- (void)setFrame:(CGRect)frame
{让cell的y值从10 的位置开始显示
frame.origin.y+=10;
让cell左右距离父控件左右间距为10
frame.origin.x+=10;
frame.size.width-=20;
设置分割线的高度
frame.size.height-=10;
// 还原系统实现
// 真正设置cell的frame
[supersetFrame:frame];
}
3 如果分割线高度太大 ,那么cel的内容可能显示不完全, 应为cell的高度减小了
怎么解决?
我们只要把cell的高度设置大一点就可以了 分割线高度设置多少 我们就在原来的基础上给cell的高度再加多少
四.发送网络请求,提示正在加载的HUD
1.为什么要使用HUD?
给用户良好的体验
2.怎么使用HUD?
用cocoapods导入SVProgressHUD框架
// 提示用户当前正在加载数据
[SVProgressHUDshowWithStatus:@"正在加载数据ing...."];
3.什么时候显示HUD
发送网络请求的时候(之前), 进入推荐标签界面就发送网络请求,所以可以在viewDidLoad方法里面显示
4.什么时候隐藏
数据加载完成或者是用户退出界面的时候
// 隐藏指示器
[SVProgressHUDdismiss];
5.注意点:
当网络非常慢的时候,用户可能不等网络请求完毕就退出当前界面,这个时候就要隐藏HUD而且关闭网络请求
那么,我们应该把代码写在哪里??
界面消失的时候回调用下面的方法,我们可以把代码写在这里面
- (void)viewWillDisappear:(BOOL)animated
{
[superviewWillDisappear:animated];
// 隐藏指示器
[SVProgressHUDdismiss];
// 干掉请求
// 让管理者中所有任务全部执行cancel
[_mgr.tasksmakeObjectsPerformSelector:@selector(cancel)];
}