• 仿写知乎日报第一周


    效果图

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    主要的逻辑

    Manager封装网络请求

    • 首先,对于获取网络请求,我是将这些方法封装成了一个类Manager,后续在获取以往的内容时又封装了一个beforeManager类用于网络请求。这里不多赘述,Manager封装网络请求的知识参考我的以往博客:iOS——Manager封装网络请求
    • 获取到网络请求之后,使用Model层的类和JSONModel来获取接收到的内容,JSONModel的知识可以参考我以往的博客:iOS——JSONModel的使用与JSONModel的嵌套,在Model层我使用了两个类,一个mainModel用于接收一开始启动程序接收的内容,一个beforeModel用于接收以往的内容。

    线程的管理

    在写知乎日报的时候,遇见了线程的问题,比如说在viewController中获取Manager网络请求的内容时,因为在viewControllert中viewDidLoad执行的很早,所以如果将View层的初始化放在viewDidLoad的话,就会先去布局好UI,等网络请求好时无法将请求到的数据赋给UI控件。所以这时候需要将View层的初始化重新放在一个实例方法loadUI中,在完成网络请求之后再去调用该loadUI方法。这时候就会发现,如果我们只是将其不加修饰写在网络请求完回调的方法时,就会报错,因为View的初始化不在主线程进行。这时我们就需要使用:

    dispatch_async(dispatch_get_main_queue(), ^{
                [self loadUI];
            });
    
    • 1
    • 2
    • 3

    使其在主线程中进行,才能解决问题。
    同样的,在后面刷新tableView时的reloadData也要使用这个方法,是因为在iOS中,reloadData方法必须在主线程上调用。

    加载网络图片

    在进行网络请求时,我发现请求到的图片内容都是url,此时我们没办法直接将其转化为图片形式,所以就要使用一个第三方库:SDWebImage库,这个库可以将我们请求到的url转为图片,其用法如下:
    首先,我们要导入该库:和Masonry、JSONModel这些的方法一样:pod ‘SDWebImage’ 即可
    然后获取我们通过网络请求到的图片的url,并且导入SDWebImage的头文件。然后使用 SDWebImage 中的 sd_setImageWithURL: 方法将网络图片加载到 UIImageView 中。
    示例:

    [yourImageView sd_setImageWithURL:[NSURL URLWithString:@"图片的url"]
                     placeholderImage:[UIImage imageNamed:@"placeholder"]];
    
    • 1
    • 2

    这将下载位于指定 URL 的图片并将其设置为 yourImageView,如果图片下载失败,将会使用 placeholder 图片作为占位符。

    左上角时间的获取

    这里我使用了NSDate来获取当前时间,并将时间转化为字符串,然后赋值给View层。

    #import <Foundation/Foundation.h>
    NS_ASSUME_NONNULL_BEGIN
    
    @interface timeModel : NSObject
    - (NSArray*)titleTimeLabel;
    @end
    
    NS_ASSUME_NONNULL_END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    #import "timeModel.h"
    
    @implementation timeModel
    
    - (NSArray *)titleTimeLabel {
        NSDate *timeDate = [NSDate date];
        NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSCalendarIdentifierGregorian];
        unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday;
        NSDateComponents *comp = [gregorian components: unitFlags fromDate: timeDate];
        NSString *month = [[NSString alloc] init];
        if (comp.month == 1) {
            month = @"一";
        }
        if (comp.month == 2) {
            month = @"二";
        }
        if (comp.month == 3) {
            month = @"三";
        }
        if (comp.month == 4) {
            month = @"四";
        }
        if (comp.month == 5) {
            month = @"五";
        }
        if (comp.month == 6) {
            month = @"六";
        }
        if (comp.month == 7) {
            month = @"七";
        }
        if (comp.month == 8) {
            month = @"八";
        }
        if (comp.month == 9) {
            month = @"九";
        }
        if (comp.month == 10) {
            month = @"十";
        }
        if (comp.month == 11) {
            month = @"十一";
        }
        if (comp.month == 12) {
            month = @"十二";
        }
        NSString *day = [NSString stringWithFormat:@"%ld", (long)comp.day];
        NSArray * timeArr = [NSArray arrayWithObjects:month, day, nil];
        return timeArr;
    }
    
    @end
    
    • 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
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    单元格的刷新

    这块我的代码还有问题,但是我初步写出了这个逻辑。我使用了- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;协议方法,当即将出现某indexPath.row位置的单元格时,就调用该方法。我使用了一个全局变量numberOfCell,其初始值为1,我的单元格的行数的返回值就是5 * numberOfCell,每当调用到该方法时,numberOfCell就会加一,因此我的单元格数量刷新后就会增加5个。当触发该方法的时候,就获取存在ManagerModel类中date属性(该属性表示当天的日期的字符串),然后将该date-1就得到前一天的时间,我还定义了一个全局变量n用于表示刷新了多少天,每当刷新一次就让n+1,因此使用date-n就能得到刷新的对应天数的字符串,再将该字符串传给beforeManager的timeStr属性,该属性用来补全https://news-at.zhihu.com/api/4/news/before/%@的url,然后进行网络请求,这样我们就获得到了刷新后的内容,再将该内容赋给对应的beforeStoriesModel类的实例的stories属性,再将该属性给单元格并刷新单元格,就实现了单元格的刷新。
    但是目前有个获取到的stories数组的越界问题,因此我只能刷新两次就崩了,这周我改正了这个问题会将解决方法写在下周的博客中。

  • 相关阅读:
    树的孩子兄弟表示法
    【无标题】
    解决:AttributeError: ‘str‘ object has no attribute ‘decode‘
    在node中实现高效率、低内存的excel/JSON转换
    Django Celery异步任务队列
    《程序员延寿指南》登GitHub热榜,最多可增寿20年?
    【SpringBoot笔记08】SpringBoot框架集成JDBC以及JdbcTemplate的使用
    [MRCTF2020]套娃 GET POST 读取字符串特性 伪造ip 伪协议伪造 file_get_contents()
    如何提高滑环的性能
    【echarts 】设置datazoom 允许使用鼠标滚轮滚动图表
  • 原文地址:https://blog.csdn.net/m0_73348697/article/details/133995145