百思不得姐之新帖(四)

一 功能成型图和该部分知识点

1 功能图:

这里写图片描述

2 学习的知识点:
—-> 1> 自定义cell
—-> 2> 图片的裁剪(两种方法)
—-> 3> 分割线的设置(三种方法)
—-> 4> 传统方法裁剪图片对app帧数的影响

二 隐藏底部tabBar

1 从整体app的功能看,当用户点击新帖左上角的按钮的时候,需要跳转页面到推荐标签中,但是需要隐藏底部的tabBar.
2 设置全局的隐藏tabBar,直接在重写的push方法里面设置
设置全局隐藏tabBar的代码:
//隐藏底部的tabBar(设置全局的隐藏tabBar)
        viewController.hidesBottomBarWhenPushed = YES;

 
 
  • 1
  • 2
  • 3
3 设置标题
self.title = @"推荐标签";
 
 
  • 1

三 模型

1 查询接口文档中,得出了模型内部需要的数据参数
2 开发中都是面对模型开发,用模型来设置数据
/**
 *  图片地址
 */
@property (nonatomic, strong) NSString *image_list;
/**
 *  订阅数
 */
@property (nonatomic, strong) NSString *sub_number;
/**
 *  名字
 */
@property (nonatomic, strong) NSString *theme_name;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

四 加载数据

1 需要用到的框架
#import <AFNetworking/AFNetworking.h>

#import <MJExtension/MJExtension.h>

#import <SVProgressHUD/SVProgressHUD.h>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
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];
        //将JSON数据转为plist文件
        [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;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
—–> 2.3> 注册cell:由于我们是采取从缓存池中去取的方案,那么就必须要注册(注意注册方法中的类型要写xib的类型)
//注册
    [self.tableView registerNib:[UINib nibWithNibName:@"XFJSubTagCell" bundle:nil] forCellReuseIdentifier:ID];
 
 
  • 1
  • 2
—–> 2.4> cell的内容:通过调用模型的set方法来赋值
#pragma mark - cell的内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //创建cell
    XFJSubTagCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];

    cell.subTagItem = self.subTagItem[indexPath.row];

    return cell;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
—–> 2.5> 设置cell的行高:这里我们先固定死cell的高度
#pragma mark - 设置行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 60;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

六 自定义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 = [image imageAntialias];
        self.XFJImageView.image = [UIImage circleImage:image];
    } ];
    //名字
    self.XFJNameLabel.text = subTagItem.theme_name;
    //订阅数量
    NSString *str = [NSString stringWithFormat:@"%@人订阅",subTagItem.sub_number];
    //转换类型
    NSInteger numStr = str.intValue;
    /***********************修改订阅数*********************/
    //判断(如果大于10000)
    if (numStr > 10000) {
        CGFloat numF = numStr / 10000.0;
        str = [NSString stringWithFormat:@"%.1f万人订阅",numF];
        //如果出现了.0那么就替换
        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
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
1.2 头像处理(方法二)
—-> 方式: 采用绘图的方法
—-> 采用原因: 在开发中需要处理更老的版本,所以我们直接用这种方法对图片的裁剪
—-> 重点: 分类(传入一张正方形图片,返回一张裁剪好的圆形图片)
+ (UIImage *)circleImage:(UIImage *)image
{
    //开启上下文
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
    //描述圆形裁剪区域(bezierPathWithOvalInRect圆形)
    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;
 
 
  • 1
代码块二: 在view加载完毕的时候调用方法中写入该段代码
self.tableView.separatorInset = UIEdgeInsetsZero;
 
 
  • 1
—–> 3.1.3 重写cell的setFrame方法(推荐使用)
—–> ​实现思路:

1> 通过取消系统tableView的分割线

//先取消系统的分割线
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
 
 
  • 1
  • 2

2> 设置tableView的背景颜色为分割线的颜色

//设置tabelView的背景颜色
    self.tableView.backgroundColor = XFJ_color(215, 215, 215);
 
 
  • 1
  • 2

3> 设置每个cell的frame的高度都减去一(重写frame色set方法)

#pragma mark - 重写frame
- (void)setFrame:(CGRect)frame
{
    //让cell的高度减去一
    frame.size.height -= 1;

    [super setFrame:frame];

}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

八 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];

    //移除SVP
    [SVProgressHUD dismiss];

    //取消请求任务
    [self.task cancel];
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

十一 总结

1 该部分主要是对tableView知识的巩固,并且新添加了一个处理同一种情况的办法,总体来说该部分不难,希望能帮到大家,也给大家一些思路.
2 大家有什么意见,请给我留言.如果觉得我的博客写得还满意的话,请关注我的官方博客,谢谢!!!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值