知乎日报——第二周

知乎日报——第二周

文章目录

  • 知乎日报——第二周
    • 本周总结
    • Model
    • View
    • Controller
      • 无限右滑
      • 预加载
    • 总结

本周总结

本周主要完成了知乎日报的详情页面,实现了无限右滑和动态申请详情页的内容,实现了预先加载。以及通过位置获取相应的格外信息,使用字典进行缓存的相关操作。大致内容如下

Nov-22-2024 11-49-20

Model

首先是相关的model建立,显示相关的新闻的详细信息以及点赞数量,我是使用了一个extraInfo和一个DetailNews的类

DetailNews

这个类主要存储的是对应新闻ID的详细信息

#import <Foundation/Foundation.h>
#import "YYModel.h"
NS_ASSUME_NONNULL_BEGIN@interface DetailNews : NSObject<YYModel>
@property (nonatomic, copy) NSString *title;          // 标题
@property (nonatomic, copy) NSString *body;           // 正文内容
@property (nonatomic, copy) NSString *imageURL;       // 主图链接
@property (nonatomic, copy) NSString *newsID;       // 分享链接
@property (nonatomic, copy) NSString *originURL;      // 原文链接
@property (nonatomic, copy) NSArray *images;        // 其他图像链接
@property (nonatomic, copy) NSString *imageHue;       // 图像色调
@end

extraInfo

这个类主要是用于存储当前页面的评论和点赞的相关信息

#import <Foundation/Foundation.h>
#import "YYModel.h"
NS_ASSUME_NONNULL_BEGIN@interface extraInfo : NSObject<YYModel,NSCopying>
@property (nonatomic, copy) NSString *newsID;
@property (nonatomic, copy) NSString *newsTopic;
@property (nonatomic, copy) NSString *newsIamge;
@property (nonatomic, assign) NSInteger longComments;
@property (nonatomic, assign) NSInteger popularity;
@property (nonatomic, assign) NSInteger shortComments;
@property (nonatomic, assign) NSInteger comments;@property (nonatomic, assign) BOOL isLiked;
@property (nonatomic, assign) BOOL isFavorited;
@endNS_ASSUME_NONNULL_END

两个BOOL类型的属性使用来存储相关的点赞和收藏状态的,当滚动视图滑动到对应的视图的时候进行调用可以展示点赞状态

View

控制器的主体有分为展示内容的ScrollView和下层展示对应新闻数据的BottomView

BottomView的具体内容如下

#import <UIKit/UIKit.h>
#import "BottomViewDelegate.h"@class extraInfo;
NS_ASSUME_NONNULL_BEGIN@interface BottomView : UIView
@property (strong, nonatomic) UIButton *back;
@property (strong, nonatomic) UIButton *like;
@property (strong, nonatomic) UIButton *comment;
@property (strong, nonatomic) UIButton *star;
@property (strong, nonatomic) UIStackView *stackView;
@property (strong, nonatomic) extraInfo *info;
@property (strong, nonatomic) NSMutableArray *isSelected;@property (nonatomic, weak) id<BottomViewDelegate> delegate;
@endNS_ASSUME_NONNULL_END#import "BottomView.h"
#import "extraInfo.h"
#import "BottomViewDelegate.h"#import "Masonry.h"
#import "DBTool.h"
@implementation BottomView
- (instancetype)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self) {[self setupView];}return self;
}//当获取到当前位置的extraInfo就进行布局
-(void)setInfo:(extraInfo *)info {_info = info;NSLog(@"%ld",info.popularity);[self.like setTitle:[NSString stringWithFormat:@"%ld",info.popularity] forState:UIControlStateNormal];[self.like setSelected:info.isLiked];[self.star setSelected:info.isFavorited];[self.like setTitle:[NSString stringWithFormat:@"%ld",info.popularity + 1] forState:UIControlStateSelected];[self.comment setTitle:[NSString stringWithFormat:@"%ld",info.comments] forState:UIControlStateNormal]  ;
}-(void)setupView {self.backgroundColor = [UIColor colorWithRed:246.0 / 256.0 green:246.0 / 256.0 blue:246.0 / 256.0 alpha:1];self.stackView = [[UIStackView alloc] init];self.stackView.axis = UILayoutConstraintAxisHorizontal;self.stackView.distribution = UIStackViewDistributionEqualSpacing;self.stackView.alignment = UIStackViewAlignmentLeading;[self addSubview: self.stackView];[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self).offset(20);make.right.equalTo(self).offset(-35);make.top.equalTo(self).offset(15);make.height.equalTo(@30);}];self.like = [UIButton buttonWithType:UIButtonTypeCustom];[self.like setImage:[UIImage imageNamed:@"dianzan-2.png"] forState:UIControlStateNormal];[self.like setImage:[UIImage imageNamed:@"dianzan.png"] forState:UIControlStateSelected];[self.like setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];self.like.titleEdgeInsets = UIEdgeInsetsMake(-12, -12, 0, 0);self.like.titleLabel.font = [UIFont systemFontOfSize:12];[self.like setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];[self.like addTarget:self action:@selector(clicklike:) forControlEvents:UIControlEventTouchUpInside];self.star = [UIButton buttonWithType:UIButtonTypeCustom];[self.star setImage:[UIImage imageNamed:@"shoucang.png"] forState:UIControlStateNormal];[self.star setImage:[UIImage imageNamed:@"shoucang-2.png"] forState:UIControlStateSelected];[self.star addTarget:self action:@selector(clickStar:) forControlEvents:UIControlEventTouchUpInside];self.comment = [UIButton buttonWithType:UIButtonTypeCustom];[self.comment setImage:[UIImage imageNamed:@"pinglun.jpg"] forState:UIControlStateNormal];self.comment.titleEdgeInsets = UIEdgeInsetsMake(-15, 0, 0, 0);self.comment.titleLabel.font = [UIFont systemFontOfSize:12];[self.comment setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];self.back = [UIButton buttonWithType:UIButtonTypeCustom];[self.back setImage:[UIImage imageNamed:@"zuojiantou.png"] forState:UIControlStateNormal];[self.stackView addArrangedSubview:self.back];[self.stackView addArrangedSubview:self.comment];[self.stackView addArrangedSubview:self.like];[self.stackView addArrangedSubview:self.star];}-(void)clickStar:(UIButton *)sender {sender.selected = !sender.selected;self.info.isFavorited = sender.selected;}-(void)clicklike:(UIButton *)sender {sender.selected = !sender.selected;self.info.isLiked = sender.selected;  
}
@end

对应展示的滚动视图即为正常的滚动视图,其显示内容为webView,我们将申请获得的URL内容,这是webView的相关操作

@implementation DetailViewController
-(void)setDetailNews:(DetailNews *)detailNews {_detailNews = detailNews;NSURL *url = [NSURL URLWithString:self.detailNews.originURL];NSURLRequest *request = [NSURLRequest requestWithURL:url];[self.webView loadRequest:request];
}- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor whiteColor];self.webView = [[WKWebView alloc] init];self.webView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;[self.view addSubview:self.webView];[self.webView mas_makeConstraints:^(MASConstraintMaker *make) {make.left.equalTo(self.view);make.right.equalTo(self.view);make.bottom.equalTo(self.view).offset(-120);make.top.equalTo(self.view);}];
}
@end

Controller

无限右滑

实现无限右滑,首先我们需要明确我们的操作,当我们向右滑的时候就会出现上一篇新闻,当这一天的新闻到最后一篇之后就需要到下一天的第一篇,这个过程我一开始想使用的当我们新闻即将滑动至申请的data数据末尾,大概是最后的两到三页时,进行网络申请,并且更新滚动视图,添加contentView的宽度,但是后面发现,如果我滑动的速度很快直接超过了申请网络请求的速度的话,数组就会直接越姐。

于是我更改了我的思路,在一开始将滚动视图布局的时候,大小就是当前控制器的持有的data元素大小,当我们右滑到边界的时候,直接添加五个contentView,在控制器之中的scrollViewDidEndDecelerating的协议方法之中添加一个定时器,只有暂停在当前页面0.5秒才开始进行相关的网络申请,然后我使用一个currentPage的属性来保存当前滑动的位置,右滑一次就加1,左滑一次就减1,再根据这个找到对应的元素。如果当前滚动视图的当前页对应元素无法被访问,即数组越界,那么我们就会进行网络申请,然后再申请过后再递归进行嵌套,判断是否越界,不越界就将信息显示在滚动视图当中

加入滚动视图的定时器和相关函数

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {CGFloat pageWidth = scrollView.frame.size.width;NSInteger newPage = (scrollView.contentOffset.x + pageWidth * 0.5) / pageWidth;if (newPage != self.currentPage) {self.currentPage = newPage;[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(loadCurrentPage) object:nil];[self performSelector:@selector(loadCurrentPage) withObject:nil afterDelay:0.5];}if (scrollView.contentOffset.x + pageWidth * 3 >= scrollView.contentSize.width - pageWidth) {self.total += 5;self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width * (self.total), 0);}
}

根据相关位置的index进行加载

- (void)loadStoryAtIndex:(NSInteger)index {NSInteger currentIndex = index;NSInteger sectionIndex = 0;for (NSArray *sectionArray in self.data) {if (currentIndex < sectionArray.count) {break;} else {currentIndex -= sectionArray.count;sectionIndex++;}}if (sectionIndex >= self.data.count) {[self requestMoreDataAndRetryWithIndex:index];return;}NSIndexPath *indexPath = [NSIndexPath indexPathForRow:currentIndex inSection:sectionIndex];Story *story = self.data[sectionIndex][currentIndex];if (!self.loadedDetailViews[indexPath]) {DetailViewController *detailVC = [[DetailViewController alloc] init];CGFloat xOffset = self.view.frame.size.width * index;detailVC.view.frame = CGRectMake(xOffset, 0, self.view.frame.size.width, self.scrollView.frame.size.height);[self addChildViewController:detailVC];[self.scrollView addSubview:detailVC.view];self.loadedDetailViews[indexPath] = detailVC;[[NetworkManager sharedManager] fetchNewsDetail:story.id completion:^(DetailNews *news, NSError *error) {if (!error && news) {detailVC.detailNews = news;}}];}if (index == self.currentPage) {extraInfo *cachedInfo = [[DBTool sharedManager] fetchInfoForNewsID:story.id];if (cachedInfo) {[self.bottomView.like setSelected:cachedInfo.isLiked];[self.bottomView.star setSelected:cachedInfo.isFavorited];} else {cachedInfo = self.extraInfoCache[story.id];if (!cachedInfo) {cachedInfo = [[extraInfo alloc] init];cachedInfo.newsID = story.id;cachedInfo.newsTopic = story.title;cachedInfo.newsIamge = [story.images firstObject];cachedInfo.isLiked = NO;cachedInfo.isFavorited = NO;}}[[NetworkManager sharedManager] fetchNewsExtraInfo:story.id completion:^(extraInfo *info, NSError *error) {if (!error && info) {cachedInfo.comments = info.comments;cachedInfo.popularity = info.popularity;[self.bottomView setInfo:cachedInfo];[self.bottomView.like setSelected:cachedInfo.isLiked];[self.bottomView.star setSelected:cachedInfo.isFavorited];self.extraInfoCache[story.id] = cachedInfo;[[DBTool sharedManager] insertInfo:cachedInfo];} else {NSLog(@"Error fetching extra info: %@", error);}}];}
}

这里,我还使用一个字典作为detailNews的缓存,每当我进行一次网络请求,我就会将当前新闻的ID作为键,申请到的detailNews为对应的值,当我滑动到当前页面时,先访问字典是否有对应的值,若有则直接使用,若是没有再进行网络申请,最后再将申请到的相关内容存入字典当中

预加载

预加载想要实现的就是当我在当前页的时候会向左右两边各自先加载一页,有利于用户进行操作,避免了网络请求的相关时间,

- (void)loadCurrentPage {[self loadStoryAtIndex:self.currentPage];if (self.currentPage > 0) {[self loadStoryAtIndex:self.currentPage - 1];}[self loadStoryAtIndex:self.currentPage + 1];}

在我们加载的函数我们传进了一个参数下标index,根据这个下标我们就可以进行对应页面的加载操作,预加载也很容易就能完成只要在翻页的时候进行loadCurrentPage的运行,改变index即可。

总结

本周完成的无限右滑以及相关的预加载等操作,确实花费了不少的时间,下个星期的目标就是完成,评论区的相关内容,用富文本以及textView完成展开评论区的相关内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/477993.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 2

七、创建前端项目 你下载了nodejs吗&#xff1f;从cn官网下载&#xff1a;http://nodejs.cn/download/&#xff0c;或者从一个国外org网站下载&#xff0c;选择自己想要的版本https://nodejs.org/download/release/&#xff0c;双击下载好的安装文件&#xff0c;选择安装路径安…

Windows 软件之 FFmpeg

文章目录 前言1 FFmpeg 视频处理1.1 编解码1.2 其它视频编辑命令1.3 视频抽帧 2 FFmpeg 音频处理3 FFmpeg 图片处理3.1 编解码3.2 拼接图片3.3 图片合成视频 附录1&#xff1a;mediainfo.ps1 前言 FFmpeg 是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的…

Docker1:认识docker、在Linux中安装docker

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

MATLAB的addpath和rmpath函数增加或删除路径

在进行MBD建模开发时&#xff0c;模型生成代码时常需要加载一些其他的文件&#xff0c;例如代码生成模版文件cgt文件、模型所涉及的头文件&#xff0c;这个时候可以在模型的回调函数中使用addpath和rmpath函数加载和删除路径&#xff0c;例如设置模型的加载之前的回调函数在模型…

【FPGA开发】Vivado自定义封装IP核,绑定总线

支持单个文件的封装、整个工程的封装&#xff0c;这里用单个文件举例。 在文件工程目录下&#xff0c;自建一个文件夹&#xff0c;里面放上需要封装的verilog文件。 选择第三个&#xff0c;指定路径封装&#xff0c;找到文件所在目录 取个名&#xff0c;选择封装IP的路径 会…

前端速通(CSS)

1.CSS介绍 1.什么是CSS? CSS&#xff08;Cascading Style Sheets&#xff0c;层叠样式表&#xff09;是一种用于控制网页的外观和布局的样式表语言。它与HTML&#xff08;超文本标记语言&#xff09;紧密配合&#xff0c;负责页面元素的样式定义&#xff0c;如字体、颜色、尺…

Android 13 编译Android Studio版本的Launcher3

Android 13 Aosp源码 源码版本 Android Studio版本 Launcher3QuickStepLib (主要代码) Launcher3ResLib(主要资源) Launcher3IconLoaderLib(图片加载&#xff0c;冲突资源单独新建) 需要值得注意的是&#xff1a; SystemUISharedLib.jar 有kotlin和java下的&#xff0c;在 Lau…

idea添加版权信息

1、添加Copyright Profiles 打开Settings -> Editor -> Copyright -> Copyright Profiles -> 新增 Copyright (c) 【你的版权信息】 【开始年份】-${today.year}. All rights reserved.如&#xff1a; Copyright (c) by cwp 2024-${today.year}. All rights rese…

【计算机网络】多路转接之poll

poll也是一种linux中的多路转接方案(poll也是只负责IO过程中的"等") 解决&#xff1a;1.select的fd有上限的问题&#xff1b;2.每次调用都要重新设置关心的fd 一、poll的使用 int poll(struct pollfd *fds, nfds_t nfds, int timeout); ① struct pollfd *fds&…

【C语言】深入剖析 C 语言中数组与指针的紧密联系及高效应用

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;例一&#xff1a;指针偏移遍历数组1.1 代码回顾1.2 代码分析1.3 理论扩展&#xff1a;数组与指针的关系1.4 数组与指针的应用场景 &#x1f4af;例二&#xff1a;自定义…

基于SpringBoot的数据结构系统设计与实现(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

算法训练-双指针

双指针 leetcode392. 判断子序列 法一&#xff1a;动态规划 法二&#xff1a;双指针 leetcode876. 链表的中间结点 法一&#xff1a;链表数组 法二&#xff1a;快慢指针 leetcode160. 相交链表 法一&#xff1a;双指针 leetcode167. 两数之和 II - 输入有序数组 法一&…

零基础学指针(上)

系列文章目录 &#x1f388; &#x1f388; 我的CSDN主页:OTWOL的主页&#xff0c;欢迎&#xff01;&#xff01;&#xff01;&#x1f44b;&#x1f3fc;&#x1f44b;&#x1f3fc; &#x1f389;&#x1f389;我的C语言初阶合集&#xff1a;C语言初阶合集&#xff0c;希望能…

shell编程之sed

sed 是一种流编辑器&#xff0c;它是文本处理中非常有用的工具&#xff0c;能够完美的配合正则表达式使用&#xff0c;处理时&#xff0c;把当前处理的行存储在临时缓冲区中&#xff0c;称为模式空间&#xff0c;接着用sed 命令处理缓冲区中的内容&#xff0c;处理完成 后&…

一文学习开源框架OkHttp

OkHttp 是一个开源项目。它由 Square 开发并维护&#xff0c;是一个现代化、功能强大的网络请求库&#xff0c;主要用于与 RESTful API 交互或执行网络通信操作。它是 Android 和 Java 开发中非常流行的 HTTP 客户端&#xff0c;具有高效、可靠、可扩展的特点。 核心特点 高效…

多目标优化算法:多目标极光优化算法(MOPLO)求解ZDT1、ZDT2、ZDT3、ZDT4、ZDT6,提供完整MATLAB代码

一、极光优化算法 极光优化算法&#xff08;Polar Lights Optimization, PLO&#xff09;是2024年提出的一种新型的元启发式优化算法&#xff0c;它从极光这一自然现象中汲取灵感。极光是由太阳风中的带电粒子在地球磁场的作用下&#xff0c;与地球大气层中的气体分子碰撞而产…

【贪心算法第二弹——2208.将数组和减半的最小操作数】

1.题目解析 题目来源 2208.将数组和减半的最小操作数——力扣 测试用例 2.算法原理(贪心策略) 3.实战代码 class Solution { public:int halveArray(vector<int>& nums) {priority_queue<double> hash;double sum 0.0;for(auto e : nums){hash.push(e);sum …

2024最新python使用yt-dlp

2024最新python使用yt-dlp下载YT视频 1.获取yt的cookie1&#xff09;google浏览器下载Get cookies.txt LOCALLY插件2&#xff09;导出cookie 2.yt-dlp下载[yt-dlp的GitHub地址](https://github.com/yt-dlp/yt-dlp?tabreadme-ov-file)1&#xff09;使用Pycharm(2024.3)进行代码…

深入理解下oracle 11g block组成

深层次说&#xff0c;oracle数据库的最少组成单位应该是块&#xff0c;一般默认情况下&#xff0c;oracle数据库的块大小是8kb&#xff0c;其中存储着我们平常所需的数据。我们在使用过程中&#xff0c;难免会疑问道&#xff1a;“oracle数据块中到底是怎样组成的&#xff0c;平…

2024年12月Gesp七级备考知识点拾遗第一期(图的定义及遍历)

目录 总序言 知识点拾遗​编辑 度数 环 二叉树 图的遍历 深度优先 广度优先 连通与强连通 有什么不同 构成分别至少需要几条边&#xff08;易错题&#xff09;&#xff1f; 无向连通图 有向强连通图 完全图 什么是完全图 无向完全图最少边数 有向完全图最少边…