【iOS】App仿写--天气预报

news2024/10/7 16:16:06

文章目录

  • 前言
  • 一、首页
  • 二、搜索界面
  • 三、添加界面
  • 四、浏览界面
  • 总结


前言

最近完成了暑假的最后一个任务——天气预报,特此记录博客总结。根据iPhone中天气App的功能大致可以将仿写的App分为四个界面——首页,搜索界面,添加界面,浏览界面,同时在天气预报中调用了较多的API,具体使用方法可以看这篇博客——【iOS】json数据解析以及简单的网络数据请求,这里不再说明

一、首页

对于首页,笔者将北京作为城市数组的第一个元素,后续可以通过搜索界面与添加界面对首页的城市进行添加
在这里插入图片描述
这里需要注意的是,因为我们的天气是实时变化的,所以我们只需要得到添加的城市名,然后通过城市名来得到实时的天气

另外需要注意的是因为我们的每个城市的天气的背景图片是不同的,然而我们自定义cell的在其出列时就已经被设置好,后面再去在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;方法中设置背景图片就会将自定义cell中原本自定义的控件覆盖掉

所以需要如下代码设置我们的背景图片:

    NSString *imageName = [NSString stringWithFormat:@"%ld.jpg", (indexPath.section + 1)];
    UIImage *image = [UIImage imageNamed:imageName];

    // 创建一个 UIImageView,并设置其内容为图片
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = cell.contentView.bounds;
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    imageView.clipsToBounds = YES;

    // 将 UIImageView 添加到 cell.contentView 的底部
    [cell.contentView insertSubview:imageView atIndex:0];

这样就做到了我们的背景图片不会覆盖我们cell中的控件,当然我们也可以在我们的对应的TableViewCell函数中设置我们的背景图片,只不过这样设置的背景图片比较单一,所以这里在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;方法中进行设置。


二、搜索界面

首先我们来看一下我们搜索界面的效果
在这里插入图片描述
可以看到我们的搜索结果会根据输入的文字进行实时变化

笔者这里使用的搜索栏是UISearchBar,我们在h文件中添加对应协议使用监听,即可实现我们的搜索的实时变化

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;   // called when text changes (including clear)

三、添加界面

我们先来看一下效果
在这里插入图片描述
可以看到我们这里利用搜索界面打开对应城市区县的天气之后点击添加按钮,相应的城市或区县就会被添加到首页,这里实际上使用了我们的通知传值,同样的,如果存在相同城市,那么就添加失败。具体有关通知传值的方法可以看这篇博客——【iOS】多界面传值
在这里插入图片描述

//添加界面
- (void)addCity {
    int boo = 0;
    for (id object in _hasCityArray) {//判断是否存在相同城市
        if ([object isEqualToString:_cityID]) {
            boo = 1;
            break;
        }
    }
    if (boo == 0) {//不存在
        [_dictionary setValue:_cityID forKey:@"key"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"notice" object:nil userInfo:_dictionary];
        NSLog(@"%@", _cityID);
        [self dismissViewControllerAnimated:YES completion:nil];
    } else {//存在
        self.alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"该城市已存在" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        }];
        [self.alert addAction:confirmAction];
        [self presentViewController:self.alert animated:YES completion:nil];
    }
}

//首页界面
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotice:)
name:@"notice" object:nil];

- (void)receiveNotice:(NSNotification *)send {
    [_cityIDArray addObject:send.userInfo[@"key"]];
    [self createData];
}

另外在这里笔者使用了SVGKit第三方库,因为在笔者调用的API中图标是以SVG的格式给出的,但是原生的Xcode并不支持SVG格式的图片,因此需要用到第三方库SVGKit,具体怎么使用第三方库在这篇博客【iOS】Cocoapods的安装以及使用中已经讲解过如何使用。

但是需要注意的一点是我们导入的SVGKit无法直接使用,会出现如下的问题 "Module 'CocoaLumberjack' not found" using CocoaPods,这是CocoaPods本身的问题,如何解决这个问题,笔者在这篇回答中找到了答案——Build problem “Module ‘CocoaLumberjack’ not found” using CocoaPods #543
在这里插入图片描述


笔者在这里给出部分API的调用代码供大家参考

- (void)creatUrl_Days {
//    //1.创建请求地址
    NSString *urlString = [NSString stringWithFormat:@"https://devapi.qweather.com/v7/weather/7d?location=%@&key=4c75fbc6961d404289bf6b44d9009576", _cityID];


    //处理字符
    urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    //创建URL
    NSURL *url = [NSURL URLWithString:urlString];
    NSLog(@"%@", urlString);
    
    //2.创建请求类
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    //3.创建会话
    //delegateQueue 表示协议方法在哪个线程中执行
	//    NSURLSession *session = [NSURLSession sharedSession];用于简单的网络请求
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self  delegateQueue:[NSOperationQueue mainQueue]];
    
    //4.根据会话创建任务
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
              // 请求出错处理
          } else {
              NSDictionary *weatherData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
              int count = 0;
              if (error) {
                  // 解析数据出错处理
              } else {
                  // 解析数据成功
                  NSArray *dailyArray = weatherData[@"daily"];
                  if (dailyArray.count > 0) {
                      for (NSDictionary *currentDayData in dailyArray) {
                          NSString *temperature_Low = currentDayData[@"tempMin"]; // 低
                          NSString *temperature_High = currentDayData[@"tempMax"]; // 低
                          NSString *temperature = [NSString stringWithFormat:@"%@°~%@°", temperature_Low, temperature_High];
                          
                          NSString *timeString = currentDayData[@"fxDate"]; // 时间
                          NSLog(@"%@", timeString);
                          NSString *time = [timeString substringWithRange:NSMakeRange(5, 5)];
                          
                          NSString *icon = currentDayData[@"iconDay"];
                                                    
                          // 将时间和温度分别添加到数组中
                          [self.dayArray_Days addObject:time];
                          [self.iconArray_Days addObject:icon];
                          [self.temperatureArray_Days addObject:temperature];

//                          NSLog(@"%@的温度为:%@, 图标代码为%@", time, temperature, icon);
//                          break;
                          if (count == 0) {
                              self->_highestT.text = [NSString stringWithFormat:@"最高%@°", temperature_High];
                              self->_lowestT.text = [NSString stringWithFormat:@"最低%@°", temperature_Low];
                              count++;
                              self->_sunRise = currentDayData[@"sunrise"];
                              self->_sunSet = currentDayData[@"sunset"];
                              self->_precip = currentDayData[@"precip"];
                              self->_uvIndex = currentDayData[@"uvIndex"];
                              NSLog(@"%@, %@", self->_sunRise, currentDayData[@"sunrise"]);

                          }

                      }
                      [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                          [self->_tableView2 reloadData];
                          [self->_tableView3 reloadData];
                          [self->_tableView4 reloadData];
                          [self->_tableView5 reloadData];
                          [self->_tableView6 reloadData];
                      }];
                  } else {
                      NSLog(@"无法获取当前时间的天气数据。");
                  }
              }
          }
        
      }];

      // 启动数据任务
      [dataTask resume];
  }

这里需要注意的是笔者这里将从API得到的数据存到对应的数组中, 然后在将数组中的元素呈现到我们的自定义cell上。

同时这里给出笔者调用的对应的API
每日天气预报

四、浏览界面

在这里插入图片描述
笔者这里将首页中的城市都传入了浏览界面,核心思路就是利用我们的UIScrollView,我们先前实现轮播图的思路是在UIScrollView中添加图片实现滚动,我们这里就将图片换成对应城市的视图控制器即可

//首页
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ScrollViewController *t = [[ScrollViewController alloc] init];
    t.cityIDArray = _cityIDArray;
    t.nowPage = indexPath.section;
    t.modalPresentationStyle = 0;
    [self presentViewController:t animated:YES completion:nil];
}

//ScrollViewController添加对应城市视图
for (int i = 0; i < _cityIDArray.count; i++) {
    CGFloat xOffset = i * self.view.bounds.size.width;
    MenuShowViewController *t = [[MenuShowViewController alloc] init];
    t.cityID = _cityIDArray[i];
    NSString *t1 = [NSString stringWithFormat:@"%d.jpg", (i + 1)];
    t.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:t1].CGImage);
    t.view.frame = CGRectMake(xOffset, 0, self.view.bounds.size.width, self.view.bounds.size.height);
    [self addChildViewController:t];
    [self.scrollView addSubview:t.view];
    [t didMoveToParentViewController:self];
}

同时笔者这里给出实现pageControl固定在视图底部的实现代码

self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height -
50, self.view.bounds.size.width, 50)];
self.pageControl.numberOfPages = _cityIDArray.count;
self.pageControl.currentPage = self.nowPage;
self.pageControl.pageIndicatorTintColor = [UIColor grayColor]; // 未选中页码的颜色
self.pageControl.currentPageIndicatorTintColor = [UIColor blackColor]; // 当前选中页码的颜色
[self.view addSubview:self.pageControl];

其实核心就是[self.view addSubview:self.pageControl];无论我们的ScrollView如何滚动,我们的view是不变的,因此将pageControl添加到view中即可实现分页控件的固定


总结

暑假的App仿写已经全部写完,后面回去学习一些第三方库例如Masonry与AFNetworking

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/830945.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基金公司最佳实践:如何用价值流分析,洞察研发效能瓶颈?

近日&#xff0c;ONES 受邀参加 QECon 2023 全球软件质量&效能大会&#xff08;北京站&#xff09;。在会上&#xff0c;ONES 高级研发总监&首席解决方案架构师陈亮宇&#xff0c;发表了主题为《聚焦价值流分析&#xff0c;寻找研发效能的「北极星」》的演讲&#xff0…

NSX 4.1中新的网络和高级安全功能介绍

我们很高兴地宣布VMware NSX 4.1全面上市&#xff0c;该版本为私有云、混合云和多云的虚拟化网络和高级安全提供了新功能。该版本的新特性和功能将使VMware NSX客户能够利用增强的网络和高级安全&#xff0c;提高运营效率和灵活性&#xff0c;并简化了故障排除的过程。 领先于…

使用免费MES系统的成功经验

随着科技的发展和数字化时代的到来&#xff0c;越来越多的工厂开始采用生产管理软件来提高生产效率和管理水平。 本文将分享一家工厂在使用免费生产管理软件后的成功经验&#xff0c;希望对广大读者有所帮助。 “之前也是在市面上找了很多厂家咨询报价&#xff0c;少则十几万多…

shell脚本清理redis模糊匹配的多个key,并计算释放内存大小

#!/bin/bash# 定义Redis服务器地址和端口 REDIS_HOST"localhost" REDIS_PORT6380# 获取Redis当前内存使用量&#xff08;以字节为单位&#xff09; function get_redis_memory_usage() {redis-cli -h $REDIS_HOST -p $REDIS_PORT INFO memory | grep "used_memo…

一个页面多触发事件需要共用一个接口处理数据,封装回调函数方法回调处理数据

// 事件共用方法queryData(code,data,callback){let params{code:code, //根据实际情况传入参数data:data //根据实际情况传入参数} // 传入借口参数this.$axios({url:, // 接口url地址method:post, // 接口类型params:params // 接口接收参数}).then((res)>{if(res&am…

有防水性能不错的耳机吗?这几款耳机游泳的时候都可以戴

Hey&#xff0c;朋友们&#xff01;清爽初夏是不是又到了减肥塑形的好时候了呢&#xff1f;不知道有没有喜欢一边运动一边听音乐的小伙伴呢&#xff1f;运动健康的同时又放松心情确实一举多得。不过现在市面上大多数耳机都不适合我们在运动中携带&#xff0c;常常会因为我们运动…

【工具】自动搜索Research网站的学术会议排名

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] Research.com是一个可以搜索学术会议网站的影响因子的网站。 好用是好用&#xff0c;但有一个缺点&#xff1a;得手动选择类目。有这么多类目&#xff0c;一个个手动选也太累了。 所以做了一个自动搜索的小工具&a…

图片资源

1.TextureType&#xff1a; Default&#xff1a;默认图片类型 Normal&#xff1a;法向贴图 Editor GUI&#xff1a;编辑器使用的图片 Sprite&#xff1a;精灵格式图片 Cursor&#xff1a;鼠标贴图 Cookie&#xff1a;灯光Cookie贴图 Lightmap&#xff1a;灯光贴图 Single…

aws的EC2云服务器自己操作记录

亚马逊官网有免费试用1年的服务器 以下内容参考 1. 启动生成实例 1.1 创建实例时需要生成 使用的默认的 Debian 和 一个.pem后缀的秘钥 1.2 网上下一个Mobaxterm ,实例名是公有 IPv4 DNS 地址 ,使用SSH连接,登录名是admin 1.3 登录进去后 输入用户名 admin 后进去,sudo …

【赠书活动|第三期《Spring Cloud Alibaba核心技术与实战案例》】

文章目录 特色内容简介作者简介抽奖方式 特色 不留遗漏&#xff1a;全面覆盖Dubbo核心知识点 直击要害&#xff1a;实战化案例精准定位技术细节 学以致用&#xff1a;精要式演示确保开发、学习不脱节 潜移默化&#xff1a;研磨式知识讲解渗透技术要点 提升效率&#xff1a;垂直…

W5100S-EVB-PICO做DNS Client进行域名解析

前言 在上一章节中我们用W5100S-EVB-PICO通过dhcp获取ip地址&#xff08;网关&#xff0c;子网掩码&#xff0c;dns服务器&#xff09;等信息&#xff0c;给我们的开发板配置网络信息&#xff0c;成功的接入网络中&#xff0c;那么本章将教大家如何让我们的开发板进行DNS域名解…

【网络安全带你练爬虫-100练】第16练:使用session发送请求

目录 一、目标1&#xff1a;使用seesion进去请求 二、网络安全O 一、目标1&#xff1a;使用seesion进去请求 &#xff08;1&#xff09;应用&#xff1a; 通过创建会话&#xff08;session&#xff09;对象来请求并爬取返回的数据包 情景&#xff1a;需要登录才能爬取的网…

深度学习Redis(4):哨兵

前言 在 Redis&#xff08;3&#xff09;&#xff1a;主从复制 中曾提到&#xff0c;Redis主从复制的作用有数据热备、负载均衡、故障恢复等&#xff1b;但主从复制存在的一个问题是故障恢复无法自动化。本文将要介绍的哨兵&#xff0c;它基于Redis主从复制&#xff0c;主要作…

HET-1型多功能二维材料转移平台

HET-1型多功能二维材料转移平台 产品介绍 HET-1型二维转移平台适用于石墨烯、各类过渡金属化合物、黑磷等多种单层及其多层二维材料的精确定位转移及范德瓦尔斯异质结的准确制备&#xff0c;实现了低维材料转移的精确可视化操作。本套转移平台由转移台模块、样品台模块、显微观…

高性能API设计

背景 设计出一个高性能的API&#xff0c;需要综合网络、业务、数据库的优化。一下是我在实际的开发过程中总结的优化思想和一些效率提升的技巧。 批量思想 很多的数据库操作都含有batch或者bulk的api&#xff0c;如我最近常使用的mybatis、mybatis plus以及elastic Search的…

怎么让表格中的一行数据 转置 为一列数据 (WPS )

例如 我现在有一列数据 我想要 变成一行 数据 1.首先选中想要转置的数据&#xff0c;然后control C 2.接着 点击你想放置数据的位置 右键 其实 关键是 找到 选择性复制 3. 找到转置&#xff0c;勾选 最后 确定 反之亦然

GD32F103VET输出PWM波形

GD32F103VET将TIMER0_CH3映射到PE14引脚&#xff0c;使其输出PWM波形。测试时&#xff0c;使用示波器看PE14引脚输出的波形&#xff0c;效果更直观。 TIMER0之PWM输出引脚映射如下: TIMER0_REMAP[1:0]"00"(没有映射): TIMER0_CH0默认被映射到PA8引脚 TIMER0_CH1默认…

计算机网络 深入理解HTTPS协议证书

文章目录 一、HTTPS协议二、对称加密三、非对称加密&对称加密(混合加密)三、加密证书四、HTTPS双刃性 一、HTTPS协议 之前介绍了HTTP协议&#xff0c;它给我们带来很大便利&#xff0c;但是也能看到他的不足。由于其本身通信使用明文&#xff0c;没有进行加密&#xff0c;…

MATLAB /Simulink 快速开发STM32(使用st官方工具 STM32-MAT/TARGET),以及开发过程

配置好环境以后就是开发&#xff1a; stm32cube配置芯片&#xff0c;打开matlab添加ioc文件&#xff0c;写处理逻辑&#xff0c;生成代码&#xff0c;下载到板子中去。 配置需要注意事项&#xff1a; STM32CUBEMAX6.5.0 MABLAB2022BkeilV5.2 Matlab生成的代码CTRLB 其中关键的…

Apache RocketMQ 命令注入

漏洞简介 RocketMQ 5.1.0及以下版本&#xff0c;在一定条件下&#xff0c;存在远程命令执行风险。RocketMQ的NameServer、Broker、Controller等多个组件外网泄露&#xff0c;缺乏权限验证&#xff0c;攻击者可以利用该漏洞利用更新配置功能以RocketMQ运行的系统用户身份执行命令…