一 功能成型图和该部分知识点
1 功能图:
2 学习的知识点:
—-> 1> 自定义cell
—-> 2> 图片的裁剪(两种方法)
—-> 3> 分割线的设置(三种方法)
—-> 4> 传统方法裁剪图片对app帧数的影响
二 隐藏底部tabBar
1 从整体app的功能看,当用户点击新帖左上角的按钮的时候,需要跳转页面到推荐标签中,但是需要隐藏底部的tabBar.
2 设置全局的隐藏tabBar,直接在重写的push方法里面设置
设置全局隐藏tabBar的代码:
viewController.hidesBottomBarWhenPushed = YES;
3 设置标题
self.title = @"推荐标签";
三 模型
1 查询接口文档中,得出了模型内部需要的数据参数
2 开发中都是面对模型开发,用模型来设置数据
/**
* 图片地址
*/
@property (nonatomic, strong) NSString *image_list;
/**
* 订阅数
*/
@property (nonatomic, strong) NSString *sub_number;
/**
* 名字
*/
@property (nonatomic, strong) NSString *theme_name;
四 加载数据
1 需要用到的框架
#import <AFNetworking/AFNetworking.h>
#import <MJExtension/MJExtension.h>
#import <SVProgressHUD/SVProgressHUD.h>
2 具体实现步骤
—> 2.1 创建会话管理者
—> 2.2 设置请求参数
—> 2.3 写成plist文件,查看文件中哪些数据是有用的(主要是方便查看哪些数据是模型中必须要展示的)
—> 2.4 发送请求
—–> 2.4.1 字典转模型
—–> 2.4.2 刷新表格
—–> 2.4.3 添加指示器
3 代码部分(由于可能需要些的代码量比较多,那么我们抽一个方法写)
#pragma mark - 加载数据的方法
- (void)setUpData
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[@"a"] = @"tag_recommend";
dict[@"c"] = @"topic";
dict[@"action"] = @"sub";
[SVProgressHUD showWithStatus:@"正在加载数据..."];
_task = [manager GET:@"http://api.budejie.com/api/api_open.php" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
self.subTagItem = [XFJSubTagItem mj_objectArrayWithKeyValuesArray:responseObject];
[SVProgressHUD dismiss];
[self.tableView reloadData];
[responseObject writeToFile:@"/Users/xiaofeng/Desktop/BuDeJie/sub.plist" atomically:YES];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
[SVProgressHUD dismiss];
}];
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
五 tableView的数据源方法
1 根据cell的内容可以判断,每个cell的内容是不变的,所以我们自定义cell—–>通过xib来描述
2 tableView的数据源方法:
—–> 2.1> 总共有多少组:由总体的页面效果显示,只需要一组,但是如果该方法不写的话,那么默认就是为一组
—–> 2.2> 行数:取决于装在数组中的模型的总数
#pragma mark - 行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.subTagItem.count;
}
—–> 2.3> 注册cell:由于我们是采取从缓存池中去取的方案,那么就必须要注册(注意注册方法中的类型要写xib的类型)
[self.tableView registerNib:[UINib nibWithNibName:@"XFJSubTagCell" bundle:nil] forCellReuseIdentifier:ID];
—–> 2.4> cell的内容:通过调用模型的set方法来赋值
#pragma mark - cell的内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
XFJSubTagCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];
cell.subTagItem = self.subTagItem[indexPath.row];
return cell;
}
—–> 2.5> 设置cell的行高:这里我们先固定死cell的高度
#pragma mark - 设置行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}
六 自定义cell
1 重写自定义中模型的set方法(注意先定义模型属性)
2 在set方法里面给xib中的属性赋值
3 设置占位图片
4 设置订阅数
<—-> 具体代码:
#pragma mark - 用模型给属性赋值(裁剪头像的第二种方法)
- (void)setSubTagItem:(XFJSubTagItem *)subTagItem
{
_subTagItem = subTagItem;
[self.XFJImageView sd_setImageWithURL:[NSURL URLWithString:subTagItem.image_list] placeholderImage:[UIImage imageNamed:@"defaultUserIcon"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (image == nil) {
return ;
}
self.XFJImageView.image = [UIImage circleImage:image];
} ];
self.XFJNameLabel.text = subTagItem.theme_name;
NSString *str = [NSString stringWithFormat:@"%@人订阅",subTagItem.sub_number];
NSInteger numStr = str.intValue;
if (numStr > 10000) {
CGFloat numF = numStr / 10000.0;
str = [NSString stringWithFormat:@"%.1f万人订阅",numF];
str = [str stringByReplacingOccurrencesOfString:@"%.0" withString:@""];
}
self.XFJTagLabel.text = str;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
七 细节处理
1 细节一: 头像的处理
2 细节二: 订阅数的处理
3 细节三: 分割线处理
1.1 头像处理(方法一)
—-> 1.1.1 该方法导致的影响: 会造成帧数下降(在ios9中,苹果修复了帧数会下降的问题,但是在ios8之前,问题还是存在的)
—-> 1.1.2 帧数下降: 会影响页面的流畅度
—-> 1.1.3 在加载xib的时候调用,我们可以将代码裁剪头像的方法写入该方法中
- (void)awakeFromNib
{
[super awakeFromNib];
self.XFJImageView.layer.cornerRadius = self.XFJImageView.XFJ_Width * 0.5;
self.XFJImageView.clipsToBounds = YES;
}
1.2 头像处理(方法二)
—-> 方式: 采用绘图的方法
—-> 采用原因: 在开发中需要处理更老的版本,所以我们直接用这种方法对图片的裁剪
—-> 重点: 分类(传入一张正方形图片,返回一张裁剪好的圆形图片)
+ (UIImage *)circleImage:(UIImage *)image
{
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
[bezierPath addClip];
[image drawAtPoint:CGPointZero];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
—-> 2.1 订阅数处理(在第六点完成了)
3.1 分割线处理(三种方法)
—–> 处理原因: 实现了上面的代理之后,但是仔细观察tableView测每个cell,我们可以看出来,出现在cell之间的分割线并不完整,并不是占据全屏.
—–> 设置原因: 让cell之间的间隙显示的更加分明,使得界面美观,更加的吸引消费者眼球
—–> 3.1.1 自定义分割线(第一种:不推荐使用;原因:太麻烦)
—–> 思路: 创建一个UIView,将UIView的尺寸长度设置和屏幕一样宽,但是UIView的宽度尽可能的小,然后插入到每个cell之间,设置下UIView的背景颜色就可以了(我这里就不细说了,你们自己实现)
—–> 3.1.2 利用系统属性(第二种:不推荐使用)
—–> 缺点: 1> ios6过渡到—> ios7才有的;2> ios7过渡到—> ios8又会多出边距;3> 不能支持ios8
代码块一 : 在设置cell的内容中写入该段代码
cell.layoutMargins = UIEdgeInsetsZero;
代码块二: 在view加载完毕的时候调用方法中写入该段代码
self.tableView.separatorInset = UIEdgeInsetsZero
—–> 3.1.3 重写cell的setFrame方法(推荐使用)
—–> 实现思路:
1> 通过取消系统tableView的分割线
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
2> 设置tableView的背景颜色为分割线的颜色
self.tableView.backgroundColor = XFJ_color(215, 215, 215);
3> 设置每个cell的frame的高度都减去一(重写frame色set方法)
#pragma mark - 重写frame
- (void)setFrame:(CGRect)frame
{
frame.size.height -= 1;
[super setFrame:frame];
}
八 UITableView的底层实现
问题:
1 cell的位置,尺寸是谁计算的?
—> 解答: 系统的tableView
2 cell的位置,尺寸什么时候开始计算的?
—> 一开始就会把所有cell的位置全部计算
原理: 计算好每个cell的frame,然后保存到一个数组中,当需要显示cell的时候,就将cell的frame取出来,直接设置.
九 特别情况
注意: 当网速慢的时候,展示的数据并没有显示出来,只是过了几秒突然显示出来了,这样给用户的体验不好.用SVP框架,模拟这种情况(在请求数据的代码中已经解决)
十 模拟
注意: 用户网速非常慢,永远加载不了数据,当用户返回的时候,提示标识没有消失,给用户的体验不好.
具体做法:
1 在viewWillDidDisapper里面移除提示标识
2 取消请求任务
代码块:
#pragma mark - 当view将要消失的时候移除svp
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[SVProgressHUD dismiss];
[self.task cancel];
}
十一 总结
1 该部分主要是对tableView知识的巩固,并且新添加了一个处理同一种情况的办法,总体来说该部分不难,希望能帮到大家,也给大家一些思路.
2 大家有什么意见,请给我留言.如果觉得我的博客写得还满意的话,请关注我的官方博客,谢谢!!!!