知乎日报第一周总结
前言
笔者在本周算是正式开始写项目了,本周主要是大致完成了主页的内容,大致完成了主页面的ui以及实现了点击进入单个cell的效果,但还存在一些小问题,之后找到解决方法会补充上去。
网络异步导致视图无法加载
因为网络申请的异步经常会导致我们的视图无法实现正常的加载,会导致我们的视图已经加载好了但是上面没有任何内容。后面笔者查阅了一下资料后知道了应该在我们的block回调函数里面加入dispatch_async(dispatch_get_main_queue(), <#^(void)block#>)
,这个函数的含义是一个异步执行的GCD,他可以保证我们在其他线程的任务完成后回到主线程中执行相关函数,在iOS开发中,布局UI的工作永远都是由主线程去完成的,所以我们必须要在主线程中执行布局ui的相关函数,这里自然也包括[self.iView.tableView reloadData]
下面笔者申请网络请求后重新加载数据的部分代码:
[[Manger sharedManger] urlDataLoad:^(MainPageModel * _Nonnull model) {
self.iModel = [NSMutableArray arrayWithObject:model];
dispatch_async(dispatch_get_main_queue(), ^{
[self.iView.tableView reloadData];
[self.iView.headActivity stopAnimating];
});
}];
加载网络上的图片
这里笔者采用了一个第三方库SDWebImage
这个库来申请我们从网络上获取的图片,具体的使用同样是通过一个cocopods库来进行一个导入就可以实现一个加载网络上的图片。笔者这里就简单介绍一下如何实现一个加载网络图片:
TopContentView* iView = [[TopContentView alloc] initWithFrame:CGRectMake(i * WIDTH, 0, WIDTH, WIDTH - 20)];
[iView.imageView sd_setImageWithURL:[NSURL URLWithString:topModel.image]];
实现一个上拉刷新的效果
实现的效果图:
我们需要实现一个一个上拉刷新的一个效果,同时也需要一个加载的显示,笔者这里没有采用第三方库来实现,而是采用了UIScrollView的协议函数以及UIActivityIndicatorView这两个东西来实现,笔者这里采用的协议函数是- (void)scrollViewDidScroll:(UIScrollView *)scrollView
这个函数来实时监控他的一个滑动,在他划到最底端的时候开始进行一个网络请求申请一个新的数据:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.tag == 100) {
CGFloat x = scrollView.contentOffset.x;
//CGFloat y = scrollView.contentOffset.y;
CGFloat contentWidth = scrollView.contentSize.width;
if (x >= contentWidth - WIDTH) {
[scrollView setContentOffset:CGPointMake(WIDTH, 0) animated:NO];
NSLog(@"1");
} else if (x <= 0) {
[scrollView setContentOffset:CGPointMake(contentWidth - 2 * WIDTH, 0) animated:NO];
NSLog(@"2");
} else {
self.iView.page.currentPage = x / WIDTH - 1;
}
} else if (scrollView.tag == 101 && !self.loading) {
CGFloat y = scrollView.contentOffset.y;
CGFloat contentHeight = scrollView.contentSize.height;
CGFloat height = scrollView.bounds.size.height;
NSLog(@"%lf ? %lf", height, contentHeight);
NSLog(@"%lf", y);
if (y + height >= contentHeight + 10) { // 滑到接近底部的位置
NSLog(@"%lf", y);
[self loadData];
} else if (y < -100) {
[self download];
}
}
}
-(void)loadData {
if (self.loading) {
return;
}
self.loading = YES;
NSInteger num = [self.dateModel.headString intValue];
NSString* str = [NSString stringWithFormat:@"%ld", num - self.iModel.count + 1];
NSLog(@"%@", str);
self.iView.tableView.tableFooterView = self.iView.footerView;
[self.iView.activity startAnimating];
//[self.iView.activity startAnimating];
[[Manger sharedManger] newDateLoad:^(MainPageModel * _Nonnull model) {
[self.iModel addObject:model];
NSLog(@"%ld", self.iModel.count);
dispatch_async(dispatch_get_main_queue(), ^{
[self.iView.tableView reloadData];
[self.iView.activity stopAnimating];
self.iView.tableView.tableFooterView = nil;
self.loading = NO;
});
} andNsstring:str];
}
这里给这个视图控制器设置了一个bool型的变量,如果这个变量的为YES的时候就说明他正在加载,就会直接退出防止他进入网络申请,从而导致多次申请网络请求,从而导致了加载的问题。
还有下面的加载图案是笔者使用了一个UIActivityIndicatorView的控件,把这个空间添加到一个UIVIew上面,然后把那个UIView加到uitableView的footerView上就可以实现一个加载的效果。然后在网络申请结束之后给这个tableView的footerView重新变成nil就可以实现了,这里笔者给出一张UITabeleView中一些属性和控件的位置关系和图片:
从这张图片上我们就可以看出一条公式也就是contentOffset.y == content的顶部 和 frame.origin.y 的差值,所以只要两者接近的时候就一意味着我们其实已经滑动的快接近底部了,所以就可以进行一个网络请求,但这里其实还有一个frame
和bounds
的区别,这里笔者之后会撰写一篇博客来特别讲述这部分内容。
左上角的时间
左上角的时间笔者是采用了一个NSDate类来实现,通过NSDate来获取当前的时间从而加载到坐上角的视图中。
- (void)judgeDate {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM-dd"];
NSString* str0 = [dateFormatter stringFromDate:self.nowDate];
NSString* str = [str0 substringWithRange: NSMakeRange(0, 2)];
NSDictionary* monthDicty = @{@"01":@"正月",@"02":@"杏月",@"03":@"桃月",@"04":@"槐月",@"05":@"榴月",@"06":@"荷月",@"07":@"霜月",@"08":@"桂月",@"09":@"玄月",@"10":@"阳月",@"11":@"冬月",@"12":@"腊月"};
// NSDictionary* dataDicty = @{@"1":@"一",@"2":@"二",@"3":@"三",@"4":@"四",@"5":@"五",@"6":@"六",@"7":@"七",@"8":@"八",@"9":@"九"};
NSString* str2 = [str0 substringWithRange: NSMakeRange(3, 1)];
NSString* str3 = [str0 substringWithRange:NSMakeRange(4, 1)];
self.monthString = [monthDicty[str] copy];
self.dateString = [NSString stringWithFormat:@"%@%@", str2, str3];
self.date = [NSString stringWithFormat:@"%@%@", str2, str3];
self.month = [str copy];
self.headString = [NSString stringWithFormat:@"2024%@%@%@", str, str2, str3];
}
- (NSMutableArray*)yesterDay:(NSInteger) section {
NSInteger dateNum = [self.date intValue];
NSInteger monthNum = [self.month intValue];
NSString* dateStr = [NSString stringWithFormat:@"%ld", dateNum - section];
NSString* monthStr = [NSString stringWithFormat:@"%ld", monthNum];
return [NSMutableArray arrayWithArray:@[dateStr, monthStr]];
}
初步实现了点击cell进入网页
这里只是初步实现,采用了一个WKweb这个类来实现,具体内容会在下篇博客中讲。
小结
笔者这里还有挺多问题未解决,如无限轮播图下面的一个毛玻璃效果还未实现,以及右上角的导航栏的头像还没布局,笔者准备最后写收藏中心的时候一并加上,这周学到很多知识,也复习了很多内容,发现自己对于各类知识的掌握仍有一些问题,iOS的学习任重而道远,笔者会继续努力学习相关内容。