iOS——知乎日报小结

引言

最近在写知乎日报,今天来总结一下最近遇到的问题。

  1. 用Manager封装网络请求,之前的博客里记录过,但在一开始不会在MVC中使用,卡了一下进度。根据MVC的原则,请求数据应该在C中,这里在刷新UI时一定要回到主线程,不然会出现数据丢失的现象
- (void)test {
    [[Manager sharedManager] NetworkQuestSuccess:^(NetWorkModel* _Nonnull mainViewNowModel) {
            NSLog(@"请求成功");
        self.netModel = mainViewNowModel;
        // 回到主线程加载UI
        dispatch_async(dispatch_get_main_queue(), ^{
           // UI更新代码
            [self addUI];
        });
        } error:^(NSError * _Nonnull error) {
            NSLog(@"请求失败");
        }];
}

因为更新UI需要请求到的数据,这里利用了通知传值

- (void)addUI {
    // 通知传值传给View界面
    _homeView = [[HomeView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.view addSubview:_homeView];
    _dictionary = [NSDictionary dictionaryWithObject:self.netModel forKey:@"ansNetModel"];
    
    [[NSNotificationCenter defaultCenter]postNotificationName:@"firstSender" object:nil userInfo:_dictionary];
}
  1. 下面就是无限轮播图的一些问题
    这里我使用了n+2的方法,即如果需要轮播五张图片,那么在滚动视图上加载七张图片,其中第一张显示图片的最后一张,最后一张是显示图片的第一张,当我们划到最后一张图片时,可以立即跳转到真正的第一张,从而在视觉上达到无限轮播的效果。同理,当划到第一张时,让他立即跳转到第五张图片。
    同时在手动拖拽时根据偏移量控制page。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    int page = scrollView.contentOffset.x / WIDTH;
    NSLog(@"%d",page);
    if (page == 0) {
        _testPageControl.currentPage = page;
        // 改变偏移量到最后一张图片
        scrollView.contentOffset = CGPointMake(WIDTH * 5, 0);
        _testPageControl.currentPage = 4;
    } else if (page == 6) {
        // 改变偏移量到第一张图片
        scrollView.contentOffset = CGPointMake(WIDTH, 0);
        _testPageControl.currentPage = 0;
    } else {
        _testPageControl.currentPage = page - 1;
    }
    // 重启计时器
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(runTimer) object:nil];
    [self performSelector:@selector(runTimer) withObject:nil afterDelay:0.4];

}
- (void) changeImage {
    if (self.currentImageIndex == 5) {
        _testPageControl.currentPage = 0;
    } else {
        _testPageControl.currentPage = self.currentImageIndex;
    }
    CGFloat x = WIDTH * self.currentImageIndex + WIDTH;
    
    [_topScollView setContentOffset:CGPointMake(x, 0) animated:YES];
    if (self.currentImageIndex == 6) {
        self.currentImageIndex = 0;
        [_topScollView setContentOffset:CGPointMake(WIDTH, 0) animated:NO];
        _testPageControl.currentPage = 0;

    }
    self.currentImageIndex++;
}

这里向左滑动时,计时器有点小崩,后续补充。。。

  1. 处理完无限轮播图就到了处理加载内容的tableView了,如下所示:
    iOS——知乎日报小结_第1张图片
    这里涉及到了上拉tableView刷新的问题,刷新tableView可以根据高度去判断刷新是否需要判断数据:
    当tableview滚动到底部的时候,手机屏幕高度+contentoffset.y=contentSize.height。那么当再向上拖拽tableview到橙色区域的时候,这个时候contentoffset.y继续增大,导致手机屏幕高度+contentoffset.y > contentSize.height。
    这个时候已经说明tableView加载到了底部,这时候就应该请求数据。写在协议函数中,这里我调用了scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset方法,主要是为了加载后面的小菊花。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    NSLog(@"did end drag");
    if (self.tableView.contentOffset.y + HEIGHT> self.tableView.contentSize.height) {
        NSLog(@"!");
        [self.activityIndicator startAnimating];
        [[Manager sharedManager] questBeforeData:^(NetWorkModel* _Nonnull mainViewNowModel)  {
                NSLog(@"请求成功");
            for (int i = 0; i < 6; i++) {
                [self->_myDateArray addObject:mainViewNowModel.stories[i]];
                StoriesModel* story = mainViewNowModel.stories[i];
                [self->_downUrlArray addObject:story.url];
            }
            NSLog(@"%@", self->_downUrlArray);
            // 回到主线程加载UI
            dispatch_async(dispatch_get_main_queue(), ^{
               // UI更新代码
                [self reloadTableView];
            });
            } error:^(NSError * _Nonnull error) {
                NSLog(@"请求失败");
            }];
    }
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _myDateArray.count + 1;
}

将请求到的数据加入数组,重新加载tableView。
就可以完成上拉加载了:
iOS——知乎日报小结_第2张图片
4. 上拉刷新的小菊花。
这里可以使用iOS自带的小菊花,只需要定义属性,设定位置,以及消失出现的时间即可。

// 设置小菊花
@property (nonatomic, strong) UIActivityIndicatorView * activityIndicator;
- (void)loadflower {
    _activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyleMedium)];
    
    //设置小菊花的frame
    _activityIndicator.frame= CGRectMake(0.4 * WIDTH, 0.9 * HEIGHT, 100, 100);
    //设置小菊花颜色
    _activityIndicator.color = [UIColor redColor];
    //设置背景颜色
    _activityIndicator.backgroundColor = [UIColor clearColor];
    //刚进入这个界面会显示控件,并且停止旋转也会显示,只是没有在转动而已,没有设置或者设置为YES的时候,刚进入页面不会显示
    _activityIndicator.hidesWhenStopped = YES;
    [self addSubview:self.activityIndicator];
}
  1. 只提取NSString中的数字。
NSDate *lastDay = [NSDate dateWithTimeInterval:-24 * a * 60 * 60 sinceDate:date];//前一天
        NSString* dateString = [lastDay description];
        NSString* string = [[NSMutableString alloc] init];
        string = [dateString substringWithRange:NSMakeRange(0, 10)];
        NSCharacterSet *nonDigitCharacterSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
        //提取数字后的字符串
        string = [[string componentsSeparatedByCharactersInSet:nonDigitCharacterSet] componentsJoinedByString:@""];
  1. 当上拉刷新时,会加载数据的时间,最开始这里直接获取NSDate根据减天数去添加时间,结果会出现时间混乱的问题,最后直接开了一个存时间的数组,根据tableView的行去判断时间,就不会混乱。
// 加载上拉数据的时间
        if (indexPath.row != 1 && (indexPath.row - 1) % 6 == 0) {
            cell.dateLabel.hidden = NO;
            cell.dateLabel.text = _dateArray[(indexPath.row - 1) / 6 - 1];
        }
  1. 知乎日报中的图片加载利用了第三方库SDWebImage,只需要导入头文件
#import "UIImageView+WebCache.h"

然后可以根据图片地址获取图片

 _topImage = [[UIImageView alloc] init];
 _imageString = [_netModel.top_stories[k] valueForKey:@"image"];
 NSLog(@"%@", [_netModel.top_stories[k] image]);
 NSURL* url = [NSURL URLWithString:_imageString];
 [_topImage sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"default"]]
  1. cell的点击事件,点击cell时进入详细网页,如下所示:
    iOS——知乎日报小结_第3张图片
    这里利用了WKwebView,这里只是轻微了解了一下,知道了一下简单的用法:当点击cell后将网页地址传入c,在c中接收并加载WebView。
- (void)receiveWebView:(NSNotification*)sender {
    
    _webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    NSURL *url = [NSURL URLWithString:sender.userInfo[@"webString"]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [_webView loadRequest:request];
    [self loadScrollView];
}

你可能感兴趣的:(iOS,ios)