「OC」知乎日报第一周
前言
本周开始了知乎日报项目的编写,在前面对YYMdoel,Masnory,AFN等第三方库的学习,近期终于开始了组内必写的项目——知乎日报,这个项目使用刚刚学习到的MVVC
第一周成果
第一周的具体成果如下:
Model的分装
对于申请的相关信息,有topStory和stroy两个不同的类,我根据申请到的相关信息写出以下的两个类
Story类:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Story : NSObject
@property (nonatomic, strong) NSArray<NSString *> *images; // 图片 URL 数组
@property (nonatomic, assign) NSInteger type; // 类型
@property (nonatomic, assign) NSString *ID; // 故事 ID
@property (nonatomic, strong) NSString *ga_prefix; // GA 前缀
@property (nonatomic, strong) NSString *title; // 故事标题
@property (nonatomic, strong) NSString *hint; // 故事标题
@end
NS_ASSUME_NONNULL_END
topStory类:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface TopStory : NSObject
@property (nonatomic, strong) NSString *image;
@property (nonatomic, assign) NSInteger type;
@property (nonatomic, copy) NSString *id;
@property (nonatomic, strong) NSString *ga_prefix;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *hint;
@end
NS_ASSUME_NONNULL_END
View的编写
对于首页的编写,使用了一个TopDisplayView去分装每一个topStory之中的存储的信息,然后以及处理相关的点击逻辑。我是用来Masnory来进行布局具体内容如下
#import "TopDisplayView.h"
#import "Masonry.h"
@implementation TopDisplayView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupViews];
[self setupConstraints];
}
return self;
}
- (void)setupViews {
self.imageView = [[UIImageView alloc] init];
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
self.imageView.clipsToBounds = YES;
[self addSubview:self.imageView];
self.title = [[UILabel alloc] init];
self.title.font = [UIFont boldSystemFontOfSize:22];
self.title.numberOfLines = 0;
self.title.textColor = [UIColor whiteColor];
[self addSubview:self.title];
self.subtitle = [[UILabel alloc] init];
self.subtitle.font = [UIFont systemFontOfSize:14];
self.subtitle.textColor = [UIColor whiteColor];
[self addSubview:self.subtitle];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
blurEffectView.frame = self.bounds;
blurEffectView.alpha = 1.0;
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = blurEffectView.bounds;
gradientLayer.colors = @[(id)[UIColor colorWithWhite:1.0 alpha:0.0].CGColor,
(id)[UIColor colorWithWhite:1.0 alpha:0.8].CGColor, // 半透明
(id)[UIColor colorWithWhite:1.0 alpha:1.0].CGColor];
gradientLayer.startPoint = CGPointMake(0.5, 0.5);
gradientLayer.endPoint = CGPointMake(0.5, 1.0);
blurEffectView.layer.mask = gradientLayer;
// 4. 将模糊效果视图添加到图片视图上
[self insertSubview:blurEffectView atIndex:1];
}
- (void)setupConstraints {
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self);
}];
[self.title mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left).offset(16);
make.bottom.equalTo(self.mas_bottom).offset(-50);
make.right.equalTo(self.mas_right).offset(-16);
}];
[self.subtitle mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.title);
make.top.equalTo(self.title.mas_bottom).offset(14);
make.right.equalTo(self.title);
}];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSDictionary *info = @{@"newsID":self.newsID};
[[NSNotificationCenter defaultCenter] postNotificationName:@"detailInfo" object:nil userInfo:info];
}
@end
可以看到我们在这个重写的UIView的子类之中,添加了一个touchBegin的点击事件,这个点击事件触发了一个监听者,将会将对应点击的故事ID传回主页面,通过网络申请获取对应ID的详情页在主页推出
Controller
对于控制器,我们需要实现根据网络申请的数据进行实时的更新,就是当我们下滑时,我们需要获取前一天日期的相关内容,进行更新,我将具体内容写在了tableView的滚动协议之中,具体内容如下
-(void)LoadNetworkData {
if (self.isLoad) return;
self.isLoad = YES;
[self.loadingIndicator startAnimating];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyyMMdd"];
NSDate *current = [dateFormatter dateFromString:self.currentDate];
NSDate *previousDate = [current dateByAddingTimeInterval:-86400];
[[NetworkManager sharedManager] fetchDataNews:self.currentDate completion:^(NSArray<Story *> * _Nonnull news, NSError * _Nonnull error) {
if (error) {
NSLog(@"无法加载更多数据: %@", error);
self.isLoad = NO;
} else {
[self.rataData addObject:news];
[self.tableView reloadData];
self.currentDate = [dateFormatter stringFromDate:previousDate];
[self.loadingIndicator stopAnimating];
self.isLoad = NO;
}
}];
}
大致内容如上,面对下拉,则会进行实时更新知乎日报之中的最新内容,这里我使用了OC之中自带的UIRefreshControl进行表示加载
- (void)refreshData:(UIRefreshControl *)refreshControl {
[[NetworkManager sharedManager] fetchLatestNewsWithCompletion:^(News * _Nonnull response, NSError * _Nonnull error) {
if (error) {
NSLog(@"Error fetching latest news: %@", error);
[refreshControl endRefreshing];
} else {
self.data = [NSMutableArray arrayWithArray:response.top_stories];
self.rataData = [NSMutableArray array];
[self.rataData addObject:response.stories];
[self.tableView reloadData];
// 结束刷新动画
[refreshControl endRefreshing];
}
}];
}