当前位置: 首页 > article >正文

「iOS」——知乎日报第三周总结

知乎日报

  • 前言
  • 详情页
    • WKWebView的学习
    • 无限右滑
    • 小菊花控件
    • 工具栏
  • 总结

前言

第三周完成了详情页的逻辑,主要写了无限右滑的逻辑,对一些UI控件进行优化。


详情页

WKWebView的学习

  • WKWebView是是苹果推崇的一个新的类,它用于将一个网页嵌套在软件里。

这个类的使用方法:
该类的实例对象需要添加导航代理,因此要遵守WKNavigationDelegate协议。

//初始化该实例对象
   self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width * (self.load_real), 0, self.view.bounds.size.width, self.view.bounds.size.height)];

//设置代理模式
    self.webView.navigationDelegate = self;
//自适应高度
    self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth  | UIViewAutoresizingFlexibleHeight;
//获取网页的url,然后使用loadRequest方法加载网页
	NSURL *url = [NSURL URLWithString:self.array_url[self.load_real]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];

协议定义了一系列方法,可以监控和响应WKWebView的导航事件,常用的如下:

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
 //   NSLog(@"页面开始加载");
}

// 页面加载完成时调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    NSLog(@"页面加载完成");
}

// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
  //  NSLog(@"收到响应,决定是否跳转");
    decisionHandler(WKNavigationResponsePolicyAllow); // 允许跳转
}

// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
   // NSLog(@"发送请求,决定是否跳转");
    decisionHandler(WKNavigationActionPolicyAllow); // 允许跳转
}

// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
   // NSLog(@"页面加载失败: %@", error.localizedDescription);
}

// 接收到服务器重定向请求后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
  //  NSLog(@"接收到服务器重定向请求");
}

此处,在无限右滑中,想采用在页面开始加载调用的方法中添加代码实现预加载,但是会无限加载下去,产生bug。还在学习如何实现预加载。

无限右滑

请添加图片描述
我此处的逻辑采用点击单元格时,传入单元格的row和section以及数据数组。这样可以定位到当前数据的位置以及总共的数据数。
创建一个滚动视图,为前面所有数据留出幕布位置,调用
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView方法,计算当前位置。将所有url存入数组中,如果当前位置刚好在数组最后一个,则进行网络请求获取数据。如果不在,则当前位置就是url在数组的位置,直接进行Web的创建即可。同时维护幕布大小,每次幕布都增加一格。
主要代码:

//创建网页
-(void)LoadWeb
{
    self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * (self.number_now + self.flag_scroll), self.view.bounds.size.height);
    self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width * (self.load_real), 0, self.view.bounds.size.width, self.view.bounds.size.height)];
    
    self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth  | UIViewAutoresizingFlexibleHeight;
    
    self.webView.navigationDelegate = self;
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    
    [self.scrollView addSubview:self.webView];
    
    NSURL *url = [NSURL URLWithString:self.array_url[self.load_real]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
    [self.set_load addObject:[NSString stringWithFormat:@"%d",self.load_real] ];
}



//滑动更新数据
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    int indext = scrollView.contentOffset.x / self.view.bounds.size.width;
    self.load_real = indext;
    if(indext >= (self.number_now +self.flag_scroll - 1)) {
        self.flag_scroll++;
    }
    if(![self.set_load containsObject:[NSString stringWithFormat:@"%d",indext]]) {
        if(indext == (self.array_url.count - 1)) {
            NSString *str_new = [NSString stringWithFormat:@"%@",self.array_date[1+self.cell_falg][@"date"]];
            [[Manger sharedSingleton] NetWorkWithTheme:^(CellModel *Model) {
                [self.array_date addObject:[Model ModelToDict:Model]];
                self.cell_falg ++;
                for(int i = 0; i < [self.array_date[1+self.cell_falg][@"stories"] count]; i++) {
                    [self.array_url addObject:self.array_date[1+self.cell_falg][@"stories"][i][@"url"] ];
                }
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self LoadWeb];
                });
            } andError:^(NSError *error) {
            } andNSString:(NSString *) str_new];            
        } else {
                        [self LoadWeb];
        }
        }
}

在详情页的数据,要更新到主页中,这里采用了通知传值的方法,将数据传到主页。


//WebVC
- (void)backButtonClicked {
    NSDictionary *userInfo = @{
        @"array_date": self.array_date,
        @"cell_flag": @(self.cell_falg)
    };
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"WebViewBackNotification" object:nil userInfo:userInfo];
    
    [self.navigationController popViewControllerAnimated:YES];
}

//FirstVC
    //注册通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(WebViewBack:) name:@"WebViewBackNotification" object:nil];


- (void)WebViewBack:(NSNotification *)notification {
    NSDictionary *userInfo = notification.userInfo;
    
    self.array_data = userInfo[@"array_date"];
    self.falg = [userInfo[@"cell_flag"] intValue];
    [self.tableView_First reloadData];
}

即可实现数据的传递。

小菊花控件

定义一个UIActivityIndicatorView属性实现小菊花控件。这里在刷新前强制等待一秒,用来显示菊花控件。

//.h文件
@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    NSString *str_new = self.array_data[1+_falg][@"date"];
    if(scrollView.contentOffset.y > self.tableView_First.contentSize.height - self.view.bounds.size.height - 50) {
        // 开始加载时显示菊花控件
        [self.activityIndicator startAnimating];
        
        [[Manger sharedSingleton] NetWorkWithTheme:^(CellModel *Model) {
            // 强制等待1秒
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self.array_data addObject:[Model ModelToDict:Model]];
                self.falg++;
                
                [self.tableView_First reloadData];
                //结束菊花控件
                [self.activityIndicator stopAnimating];
            });
            
        } andError:^(NSError *error) {
            NSLog(@"xialaerror:%@",error);
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.activityIndicator stopAnimating];
            });
        } andNSString:(NSString *)str_new];
    }
}

工具栏

工具栏的按钮,可以通过设置一个UIImageView和一个Label实现。

    UIImageView *imageViewPL = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pinglunqu-pinglun.png"]];
    imageViewPL.frame = CGRectMake(0, 10, 30, 30);
    UILabel *labelPL = [[UILabel alloc] initWithFrame:CGRectMake(40, 0, 20, 20)];
    labelPL.text = @"7";
    UIView *viewPL = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
    [viewPL addSubview:imageViewPL];
    [viewPL addSubview:labelPL];
    UIBarButtonItem *btn_PL = [[UIBarButtonItem alloc] initWithCustomView:viewPL];
    btn_PL.width = 60;

总结

在无限右滑中,对实现预加载没什么思路,下周尽量实现了评论区等功能后,实现一下预加载功能。


http://www.kler.cn/a/388656.html

相关文章:

  • 【Android、IOS、Flutter、鸿蒙、ReactNative 】约束布局
  • 怎么监控员工电脑?分享5个监控员工电脑的绝佳方法(立竿见影!建议收藏!)
  • Nginx中实现流量控制(限制给定时间内HTTP请求的数量)示例
  • 3DTiles之i3dm介绍
  • 【机器学习】机器学习中用到的高等数学知识-3.微积分 (Calculus)
  • [ Linux 命令基础 3 ] Linux 命令详解-文件和目录管理命令
  • 云财务SaaS财务软件源码
  • 深入理解智能合约 ABI
  • ORU 的 Open RAN 管理平面 (M 平面)
  • 词嵌入方法(Word Embedding)
  • Openstack nova创建一台实例的过程概述
  • Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
  • Vue 3 中Pinia状态管理库的使用方法总结
  • 数据仓库之 Atlas 血缘分析:揭示数据流奥秘
  • 2024软件测试面试热点问题
  • 【51单片机4位数码管左右移位显示0-9不用数组】2022-4-19
  • 【ETL:概念、流程与应用】
  • Stable Diffusion Web UI - ControlNet 边缘特征提取 CANNY
  • Linux grep 使用正则表达式说明
  • SpringBoot中的注解详解(一)
  • 昇思大模型平台打卡体验活动:项目1基于MindSpore实现BERT对话情绪识别
  • 架构篇(04理解架构的演进)
  • 【C++】—掌握STL string类:string的模拟实现
  • 函数式编程Stream流(通俗易懂!!!)
  • 计算机学生自我提升方法——善用搜索引擎
  • 工程认证视角下的Spring Boot计算机课程管理系统