仿写知乎日报第二周

新学到的

新学到了WKWebView:

  • WKWebView是是苹果推崇的一个新的类,它用于将一个网页嵌套在软件里。这里我是将点击cell后的内容中放入WKWebView对象。
  • WKWebView的使用:
    首先,要导入这个类:
#import <WebKit/WebKit.h>

然后要为这个类的实例对象添加导航代理,因此要遵守WKNavigationDelegate协议,并且声明一个WKWebView的属性:

@interface neiRongViewController : UIViewController<UIScrollViewDelegate, WKNavigationDelegate>
@property (nonatomic, strong) WKWebView *wkwebView;

在视图控制器中,我们首先创建一个这个类的实例对象,并且为其设置导航代理:

self.wkwebView = [[WKWebView alloc] initWithFrame:self.view.bounds];
self.wkwebView.navigationDelegate = self;

然后获取对应网页的url,并使用loadRequest方法加载网页:

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", today_stories.url]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.wkwebView loadRequest:request];

WKNavigationDelegate 协议定义了一系列方法,允许你监控和响应 WKWebView 的导航事件。以下是一些常用的 WKNavigationDelegate 方法:

  1. 页面开始加载时调用

    • webView:didStartProvisionalNavigation::在开始加载一个页面时调用,通常表示已经接收到页面的主要内容,但可能还有其他资源需要加载。
  2. 页面导航发生错误时调用

    • webView:didFailProvisionalNavigation:withError::在加载页面时发生错误时调用,例如无法连接到服务器或找不到页面。
  3. 页面加载完成时调用

    • webView:didFinishNavigation::在页面成功加载完成后调用,可用于执行与页面加载相关的操作。
  4. 页面导航被重定向时调用

    • webView:didReceiveServerRedirectForProvisionalNavigation::在页面导航被服务器重定向到其他位置时调用。
  5. 页面加载失败时调用

    • webView:didFailNavigation:withError::在页面导航失败时调用,例如因为网络问题或其他原因导致加载失败。
  6. 页面加载过程中调用

    • webView:didCommitNavigation::在页面加载过程中,当接收到更多数据时调用。
  7. 页面导航操作完成时调用

    • webView:didFinishNavigation::在页面导航操作完成后调用,此时页面已完全加载。
  8. 页面加载发生错误时调用

    • webView:didFailProvisionalNavigation:withError::在加载页面时发生错误时调用,可以用于处理加载失败的情况。
  9. 处理页面身份验证时调用

    • webView:didReceiveAuthenticationChallenge:completionHandler::在需要进行身份验证时调用,你可以在此方法中提供用户凭据,例如用户名和密码。
  10. 页面内容进程终止时调用

    • webViewWebContentProcessDidTerminate::在页面内容进程意外终止时调用,你可以在此方法中处理相应的逻辑。

这些方法允许我们监控页面导航、处理导航错误、执行页面加载后的操作以及其他与 WKWebView 相关的事件。

在这里,我使用的是- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;即完成网页的获取后调用。

单元格的刷新

  • 单元格的刷新我使用了- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;协议方法,当scrollView的偏移量大于tableView的总长度时,就调用该方法。我使用了一个全局变量numberOfCell,其初始值为0,我的单元格的组数的返回值就是2 + numberOfCell,每当调用到该方法时,numberOfCell就会加一,因此我的单元格组数刷新后就会增加1个。当触发该方法的时候,就获取存在ManagerModel类中date属性(该属性表示当天的日期的字符串),然后将该date-1就得到前一天的时间,我还定义了一个全局变量n用于表示刷新了多少天,每当刷新一次就让n加1,因此使用date-n就能得到刷新的对应天数的字符串,再将该字符串传给beforeManager的timeStr属性,该属性用来补全https://news-at.zhihu.com/api/4/news/before/%@的url,然后进行网络请求,这样我们就获得到了刷新后的内容,再将该内容赋给对应的beforeStoriesModel类的实例的stories属性,再将该属性给单元格并刷新单元格,就实现了单元格的刷新。
  • 因为当天最新内容和以前内容的获取时机和api都不一样,所以我将当天的最新内容单独放在一个组,刷新获取的过往内容放在后面的组中。因为过往的内容必须一直保持一个相同的顺序,因此我将获取的过往的内容的model放在一个数组中,当要将其放在cell中时,使用indexPath.row访问数组元素来获取详细内容。
  • 代码实现:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {
        imageScrollTableViewCell *scrollCell = [self.mainview.tableView dequeueReusableCellWithIdentifier:@"idimage"];
        scrollCell.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 7, 400);
        scrollCell.scrollView.pagingEnabled = YES;
        scrollCell.scrollView.showsHorizontalScrollIndicator = NO;
        
        for (int i = 0; i < 6; i++) {
            if (i == 0) {
                top_storiesModel *top_stories = self.mainModel.top_stories[4];
                UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
                [button sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", top_stories.image]] forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@"geRen.jpg"]];
                button.frame = CGRectMake(0, 0, self.view.bounds.size.width, 400);
                button.tag = 4;
                [button addTarget:self action:@selector(scrollButtonPress:) forControlEvents:UIControlEventTouchUpInside];
                
                UILabel *title = [[UILabel alloc] init];
                title.font = [UIFont systemFontOfSize:24];
                title.numberOfLines = 2;
                title.textColor = [UIColor whiteColor];
                [button addSubview:title];
                
                [title mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(button).offset(24);
                    make.top.equalTo(button).offset(250);
                    make.width.equalTo(@374);
                    make.height.equalTo(@100);
                }];
                title.text = top_stories.title;
                
                UILabel *zuoZheTitle = [[UILabel alloc] init];
                zuoZheTitle.numberOfLines = 0;
                zuoZheTitle.textColor = [UIColor whiteColor];
                [button addSubview:zuoZheTitle];
                [zuoZheTitle mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(button).offset(24);
                    make.top.equalTo(button).offset(330);
                    make.width.equalTo(@374);
                    make.height.equalTo(@50);
                }];
                zuoZheTitle.text = top_stories.hint;
                
                [scrollCell.scrollView addSubview: button];
            } else {
                top_storiesModel *top_stories = self.mainModel.top_stories[i - 1];
                UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
                [button sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", top_stories.image]] forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@"geRen.jpg"]];
                button.frame = CGRectMake(self.view.bounds.size.width * i, 0, self.view.bounds.size.width, 400);
                button.tag = i - 1;
                [button addTarget:self action:@selector(scrollButtonPress:) forControlEvents:UIControlEventTouchUpInside];
                
                UILabel *title = [[UILabel alloc] init];
                title.font = [UIFont systemFontOfSize:24];
                title.numberOfLines = 2;
                title.textColor = [UIColor whiteColor];
                [button addSubview:title];
                
                [title mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(button).offset(24);
                    make.top.equalTo(button).offset(250);
                    make.width.equalTo(@374);
                    make.height.equalTo(@100);
                }];
                title.text = top_stories.title;
                
                UILabel *zuoZheTitle = [[UILabel alloc] init];
                zuoZheTitle.numberOfLines = 0;
                zuoZheTitle.textColor = [UIColor whiteColor];
                [button addSubview:zuoZheTitle];
                [zuoZheTitle mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(button).offset(24);
                    make.top.equalTo(button).offset(330);
                    make.width.equalTo(@374);
                    make.height.equalTo(@50);
                }];
                zuoZheTitle.text = top_stories.hint;
                
                [scrollCell.scrollView addSubview: button];
            }
        }
        top_storiesModel *top_stories = self.mainModel.top_stories[0];
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button sd_setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", top_stories.image]] forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@"geRen.jpg"]];
        button.frame = CGRectMake(self.view.bounds.size.width * 6, 0, self.view.bounds.size.width, 400);
        button.tag = 0;
        [button addTarget:self action:@selector(scrollButtonPress:) forControlEvents:UIControlEventTouchUpInside];
        
        UILabel *title = [[UILabel alloc] init];
        title.font = [UIFont systemFontOfSize:24];
        title.numberOfLines = 2;
        title.textColor = [UIColor whiteColor];
        [button addSubview:title];
        
        [title mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(button).offset(24);
            make.top.equalTo(button).offset(250);
            make.width.equalTo(@374);
            make.height.equalTo(@100);
        }];
        title.text = top_stories.title;
        
        UILabel *zuoZheTitle = [[UILabel alloc] init];
        zuoZheTitle.numberOfLines = 0;
        zuoZheTitle.textColor = [UIColor whiteColor];
        [button addSubview:zuoZheTitle];
        [zuoZheTitle mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(button).offset(24);
            make.top.equalTo(button).offset(330);
            make.width.equalTo(@374);
            make.height.equalTo(@50);
        }];
        zuoZheTitle.text = top_stories.hint;
        
        [scrollCell.scrollView addSubview: button];
        [scrollCell.scrollView setContentOffset:CGPointMake(self.view.bounds.size.width, 0)];
        return scrollCell;
    }
    mainViewTableViewCell *cell = [self.mainview.tableView dequeueReusableCellWithIdentifier:@"id" forIndexPath:indexPath];
    
    if (indexPath.section == 1) {
        storiesModel *stories = self.mainModel.stories[indexPath.row];
        cell.titleLabel.text = stories.title;
        cell.zuoZheAndTimeLabel.text = stories.hint;
        cell.picImageStr = stories.images[0];
    } else {
        for (int i = 0; i < numberOfCell; i++) {
            if (indexPath.section == i + 2) {
                if ([self.beforeArray count] == numberOfCell) {
                    beforeStoriesModel *before = self.beforeArray[i][indexPath.row];
                    cell.titleLabel.text = before.title;
                    cell.zuoZheAndTimeLabel.text = before.hint;
                    cell.picImageStr = before.images[0];
                }
            }
        }
    }
    
    return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (section == 0 || section == 1) {
        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 0)];
        return view;
    }
    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 30)];
    for (int i = 0; i < numberOfCell; i++) {
        if (section == i + 2) {
            int month = [[self.beforeTimeArray[i] substringWithRange:NSMakeRange(4, 2)] intValue];
            int day = [[self.beforeTimeArray[i] substringWithRange:NSMakeRange(6, 2)] intValue];
            UILabel *titleTimeLabel = [[UILabel alloc] init];
            [view1 addSubview:titleTimeLabel];
            titleTimeLabel.text = [NSString stringWithFormat:@"%d月%d日     ——————————————", month, day];
            titleTimeLabel.textColor = [UIColor grayColor];
            titleTimeLabel.font = [UIFont systemFontOfSize:21];
            [titleTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                make.left.equalTo(view1).offset(25);
                make.top.equalTo(view1).offset(0);
                make.width.equalTo(@(self.view.bounds.size.width));
                make.height.equalTo(@30);
            }];
        }
    }
    return view1;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    if (section == 0 || section == 1) {
        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 0)];
        return view;
    }
    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 20)];
    return view1;
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    if (scrollView.contentOffset.y > self.mainview.tableView.contentSize.height - self.view.bounds.size.height + 50) {
        self.activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame: CGRectMake(self.view.bounds.size.width / 2 - 50, self.view.bounds.size.height - 100, 80, 80)] ;
        [self.view addSubview:self.activityIndicator];
        [self.activityIndicator startAnimating];
        beforeManager *beforemanager = [beforeManager sharedBeforeManager];
        NSInteger strInt = [self.mainModel.date longLongValue];
        NSString *str = [NSString stringWithFormat:@"%ld", strInt - numberOfCell];
        beforemanager.timeStr = str;
        [beforemanager NetWorkWithBeforeData:^(beforeModel * _Nonnull beforeModel) {
            [self.beforeArray addObject:beforeModel.stories];
            [self.beforeTimeArray addObject:beforeModel.date];
            numberOfCell++;
            dispatch_async(dispatch_get_main_queue(), ^{
                sleep(1);
                [self.activityIndicator stopAnimating];
                [self.mainview.tableView reloadData];
            });

        } error:^(NSError * _Nonnull error) {
            NSLog(@"ERROE");
        }];
    }
}

点击单元格事件

  • 点击单元格后,要求是要实现页面间可以滑动,因此,对于顶部的无限轮播图,我将轮播的图片设为button,并为每个button设置tag值,点击button后,每个button的section就是它的button。然后跳转到neiRongViewController,显示的neiRongView中有一个scrollView,该scrollView的画布宽度对于顶部的轮播图来说是5 * 屏幕宽度,对于tableView中的内容来说就是所有cell数量 * 屏幕宽度。对于cell中的内容,我先将每组的Manager获取的stories放在同一个数组中,然后传入点击的cell的((int)indexPath.section - 1) * 5 + (int)indexPath.row作为其section,然后在neiRongViewController中通过section为下标来访问数组元素从而获取当前内容的url,再通过WKWebView获取网页并将其放在scrollView中,而且要根据section放在scrollView中的对应位置。
  • 同时要实现scrollView的协议方法- (void)scrollViewDidScroll:(UIScrollView *)scrollView,获取滑动滚动视图后的偏移位置,并将其作为新的section,同时调用相应方法重新获取新section的webView。要注意的是因为有些视图加载过了,再往回划的时候就要让它不要再加载一遍了,所以我使用了一个set集合,每当访问过一个section后就将当前的section加入set中,再一次调用webView方法时判断set中是否有当前元素。
  • 代码实现:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *allNeiRongArr = [[NSArray alloc] init];
    allNeiRongArr = [allNeiRongArr arrayByAddingObjectsFromArray:self.mainModel.stories];
    for (int i = 0; i < numberOfCell; i++) {
        allNeiRongArr = [allNeiRongArr arrayByAddingObjectsFromArray:self.beforeArray[i]];
    }
    if (indexPath.section != 0) {
        neiRongViewController *neiRong = [[neiRongViewController alloc] init];
        neiRong.theStories = allNeiRongArr;
        neiRong.isButton = NO;
        neiRong.allIndexNum = (1 + numberOfCell) * 5;
        neiRong.section = ((int)indexPath.section - 1) * 5 + (int)indexPath.row;
        [self.navigationController pushViewController:neiRong animated:YES];
    }
}
- (void)webViewGet {
    [self.set addObject:[NSString stringWithFormat:@"%d", self.section]];
    self.wkwebView = [[WKWebView alloc] initWithFrame:self.view.bounds];
    self.wkwebView.navigationDelegate = self;
    if (self.isButton == YES) {
        top_storiesModel *top_stories = [[top_storiesModel alloc] init];
        top_stories = self.theStories[self.section];
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", top_stories.url]];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [self.wkwebView loadRequest:request];
    } else if (self.section < 5){
        storiesModel *today_stories = [[storiesModel alloc] init];
        today_stories = self.theStories[self.section];
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", today_stories.url]];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [self.wkwebView loadRequest:request];
    } else if (self.section >= 5) {
        beforeStoriesModel *before_stories = [[beforeStoriesModel alloc] init];
        before_stories = self.theStories[self.section];
        NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@", before_stories.url]];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [self.wkwebView loadRequest:request];
    }
    [self.activityIndicator stopAnimating];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    int index = scrollView.contentOffset.x / self.view.bounds.size.width;
    NSLog(@"index :%d", index);
    self.section = index;
    if (![self.set containsObject: [NSString stringWithFormat:@"%d", self.section]]) {
        [self webViewGet];
        self.activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame: CGRectMake(self.view.bounds.size.width / 2 - 50, self.view.bounds.size.height/2 - 50, 80, 80)] ;
        [self.view addSubview:self.activityIndicator];
        [self.activityIndicator startAnimating];
    }
    self.idStr = [self.theStories[self.section] ID];
    [self getData];

}

加载控件(小菊花)

首先要定义一个UIActivityIndicatorView属性,方便我们在任何地方可以关掉该控件

//初始化该控件并设置位置
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame: CGRectMake(self.view.bounds.size.width / 2 - 50, self.view.bounds.size.height - 100, 80, 80)] ;
[self.view addSubview:self.activityIndicator];
//开启加载控件
[self.activityIndicator startAnimating];
//结束该控件
[self.activityIndicator stopAnimating];

仿写知乎日报第二周_第1张图片
仿写知乎日报第二周_第2张图片

你可能感兴趣的:(objective-c,ios,xcode,开发语言)