【iOS】知乎日报前三周总结

知乎日报前三周总结)

首页

上述图片是笔者首页的完成效果,首页中并没有特别难的部分,主要的难点就是上拉刷新以及网络申请的问题,最上方使用了一个无线轮播视图,这里的实现并不是很难,主要的问题还是关于网络申请的部分。

网络申请

网络申请笔者这里采用的是AFNetWroking以及YYModel完成的网络申请,这些内容才之前的博客中都有过讲解,这里就不多进行赘述,这里主要还面临的问题就是网络异步的问题,这里笔者使用GCD来解决这个问题,但是GCD的原理等笔者还没有学习,这里先使用来解决网络异步的问题。

objectivec 复制代码
- (void)loadImages:(long) a {
    // 使用 dispatch_group 来等待所有图片加载完成
    dispatch_group_t imageLoadGroup = dispatch_group_create();
    NSMutableArray* arrimage = [NSMutableArray array];
    for (NSDictionary *dic in self->_arrStories[a]) {
        NSArray* arr = dic[@"images"];
        NSURL *imageurl = [NSURL URLWithString:arr[0]];
        UIImageView *iview = [[UIImageView alloc] init];
        
        dispatch_group_enter(imageLoadGroup); // 进入组
        
        [iview sd_setImageWithURL:imageurl
                placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                         options:SDWebImageRefreshCached
                       completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
            if (error) {
                NSLog(@"加载图片失败: %@", error.localizedDescription);
            } else {
                NSLog(@"图片加载成功");
            }
            dispatch_group_leave(imageLoadGroup); // 离开组
        }];
        
        [arrimage addObject:iview];
    }
    [self->_arr_image addObject:arrimage];
    // 在所有图片加载完成后设置主视图
    dispatch_group_notify(imageLoadGroup, dispatch_get_main_queue(), ^{
        [self loadtopImages]; // 设置主视图
    });
}

- (void)loadtopImages {
    // 使用 dispatch_group 来等待所有图片加载完成
    dispatch_group_t imageLoadGroup = dispatch_group_create();
    
    for (NSDictionary *dic in self->_arr_top_stories) {
        NSString* arr = dic[@"image"];
        NSLog(@"%@", arr);
        NSURL *imageurl = [NSURL URLWithString:arr];
        UIImageView *iview = [[UIImageView alloc] init];
        
        dispatch_group_enter(imageLoadGroup); // 进入组
        
        [iview sd_setImageWithURL:imageurl
                placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                         options:SDWebImageRefreshCached
                       completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
            if (error) {
                NSLog(@"加载图片失败: %@", error.localizedDescription);
            } else {
                NSLog(@"图片加载成功");
            }
            dispatch_group_leave(imageLoadGroup); // 离开组
        }];
        
        [self->_arr_topimage addObject:iview];
    }
    
    // 在所有图片加载完成后设置主视图
    dispatch_group_notify(imageLoadGroup, dispatch_get_main_queue(), ^{
        [self setupMainView]; // 设置主视图
    });
}

根据上述代码可以看出,笔者这里采用一个请求嵌套一个请求的方法,避免最后更新主视图时出现空数组的情况,导致报错。

上拉刷新

这里我通过使用滚动视图的协议来判断是否tableview已经滑动到了底端,如果已经滑动到了底端,就进行网络申请,获取前一天的数据,这样就达到了一个上拉刷新的效果。

objectivec 复制代码
CGFloat y = scrollView.contentOffset.y;
        CGFloat contentHeight = scrollView.contentSize.height;
        CGFloat height = scrollView.bounds.size.height;
        if (y + height >= contentHeight + 10) {
            [self Gaindate];
        }

-(void) Gaindate {
    if(self.action)
        return;
    self.action = YES;
    [self.mainview.active startAnimating];

    NSString *strweb = @"https://news-at.zhihu.com/api/4/news/before/";
    // 使用 stringByAppendingFormat 创建一个新的字符串
    strweb = [strweb stringByAppendingFormat:@"%@", [self->_date lastObject]];
    NSLog(@"%@", strweb);
    id manager = [Manager shareManager];
    [manager URLString:strweb NetWorkWithData:^(ModelShuju * _Nonnull mainModel) {
        NSDictionary *dic = [mainModel yy_modelToJSONObject];
        NSArray *arr = dic[@"stories"];
        [self.date addObject:dic[@"date"]];
        
        // 在主线程中更新 UI
        dispatch_async(dispatch_get_main_queue(), ^{
            [self->_arrStories addObject:arr];
            [self loadImages1:(self->_arrStories.count - 1)];// 加载图片
            [self getURL:(self->_arrStories.count - 1)];
        });
    } error:^(NSError * _Nonnull error) {
        NSLog(@"error:%@", error.localizedDescription);
    }];
}

通过这两个函数就可以刷新前一天的数据。

详情页

上图即笔者的详情页,这个页面中主要的问题就是左右滑动时进行对webView的申请,还有就是对于首页和详情页之间的相互传递信息,当详情页刷新到一个没有出现的信息时,需要使用传值将信息传递回首页,同步更新内容。

WKWebView

WKWebView使用时需要添加头文件:

objectivec 复制代码
#import <WebKit/WebKit.h>

而后使用其实比较简单:

objectivec 复制代码
    NSString *urlString = _strurl[_count];
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [_webview loadRequest:request];

如上所示,就可以加载出webview了。

左右滑动

笔者这里左右滑动的逻辑上还存在一点问题,无法一次滑动多个页面跳过中间的进行webview的申请,后期还需要对这里进行一个升级,这里先展示笔者现有的逻辑。

objectivec 复制代码
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (fabs(scrollView.contentOffset.x - self.lastContentOffset.x) > fabs(scrollView.contentOffset.y - self.lastContentOffset.y)) {
            scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, self.lastContentOffset.y);
        } else {
            self.lastContentOffset = scrollView.contentOffset; // 更新位置
        }
    CGFloat widthNow = self.mainview.scroll.contentOffset.x;
    CGFloat widthbegin = self.count * 393;
    CGFloat width = self.mainview.scroll.contentSize.width;
    NSInteger cha = width - widthNow;
    NSInteger cha1 = widthbegin - widthNow;
//    NSLog(@"%ld", (long)cha1);
    if(cha == 393 && !_Right) {
        NSLog(@"开始申请");
        _Right = YES;
        self.mainview.scroll.contentSize = CGSizeMake(width + 393, 719);
        _webview = [[WKWebView alloc] initWithFrame:CGRectMake(widthNow, 0, 393, 719)];
        _webview.navigationDelegate = self;
        if(_countright < _strurl.count) {
            [self gainextra:_countright];
            NSString *urlString = _strurl[_countright];
            _countright++;
            NSLog(@"URL String: %@", urlString);
            [self gainWebview:urlString];
        } else {
            NSLog(@"重新申请");
            [self gaindate];
            
        }
    }
    if(cha1 == 393 && !_Right) {
        NSLog(@"开始申请");
        _Right = YES;
        _webview = [[WKWebView alloc] initWithFrame:CGRectMake(widthNow, 0, 393, 719)];
        _webview.navigationDelegate = self;
        [self gainextra:_countleft];
        NSString *urlString = _strurl[_countleft];
        _count--;
        _countleft--;
        NSLog(@"URL String: %@", urlString);
        [self gainWebview:urlString];
    }
}

笔者这里通过判断滑动的位置来进行网络申请,申请webview展示在滚动视图上,但是由于我的限制,不可以跳过中间的页面进行申请后面的页面,后面会更改逻辑上的问题,从而使得更加完善。

首页和详情页的数据传输

这里主要需要传输的就是当我在详情页获取到新的一天的数据,即首页中未刷新的前一天的数据时,需要将这个数据传输会首页,让首页进行一个tableview的刷新,从而使得更加的流畅和合理。其实对于首页传输到详情页而言,则更为简单,笔者这里直接使用了属性传值的方法,就不过多进行赘述了。

笔者这里使用了通知传值的方法,当我获得到新的一天的数据时,直接传递回首页。

objectivec 复制代码
NSDictionary* dictionary = @{@"stories":[self->_arrStories lastObject],@"date":[self->_arrdate lastObject]};
            [[NSNotificationCenter defaultCenter] postNotificationName:@"inform" object:nil userInfo:dictionary];

首页中:

objectivec 复制代码
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveNoticed:) name:@"inform" object:nil];
        
}
- (void)receiveNoticed:(NSNotification*)sender {
    [_arrStories addObject:sender.userInfo[@"stories"]];
    [_date addObject:sender.userInfo[@"date"]];
    [self loadImages111:(_arrStories.count - 1)];
    
}

这样就可以相互传递信息,避免了两个页面中数据不同步导致逻辑不甚合理的问题了。

总结

后面的内容笔者还在写,对于评论区的展开功能还没有写完,仅申请到了数据,还有收藏的知识点没有学习,后面的内容笔者后期还会总结,这次就先总结这么多内容。

相关推荐
Mephisto.java12 分钟前
【大数据学习 | HBASE高级】region split机制和策略
数据库·学习·hbase
Bio Coder37 分钟前
学习用 Javascript、HTML、CSS 以及 Node.js 开发一个 uTools 插件,学习计划及其周期
javascript·学习·html·开发·utools
Allen zhu1 小时前
【PowerHarmony】电鸿蒙学习记录-准备工作
学习·华为·harmonyos
华清远见成都中心1 小时前
物联网学习路线来啦!
物联网·学习
hgy89691 小时前
Ekman理论回归
学习
坚硬果壳_1 小时前
《硬件架构的艺术》笔记(一):亚稳态
笔记·学习
糊涂君-Q2 小时前
Python小白学习教程从入门到入坑------第三十一课 迭代器(语法进阶)
python·学习·程序人生·考研·职场和发展·学习方法·改行学it
qiyi.sky2 小时前
JavaWeb——Web入门(8/9)- Tomcat:基本使用(下载与安装、目录结构介绍、启动与关闭、可能出现的问题及解决方案、总结)
java·前端·笔记·学习·tomcat
dal118网工任子仪2 小时前
web安全漏洞之ssrf入门
笔记·学习·计算机网络·网络安全
安和昂2 小时前
【iOS】知乎日报第三周总结
ios