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

文章目录

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


前言

最近完成了暑假的最后一个任务——天气预报,特此记录博客总结。根据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]];//创建URLNSURL *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.rhkb.cn/news/77358.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

blender的下载安装和配置中文环境

引言 在3D建模和动画设计领域&#xff0c;Blender 作为一款强大且免费的开源软件&#xff0c;一直以优秀的性能和对众多技术的支持赢得了大批用户的喜爱。然而&#xff0c;对于刚接触这款软件的用户而言&#xff0c;其安装和配置过程可能会带来一定困扰&#xff0c;尤其是在设…

Leetcode-每日一题【剑指 Offer 04. 二维数组中的查找】

题目 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右 非递减 的顺序排序&#xff0c;每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该整数。 示例: 现有矩阵 matri…

公文写作技巧:“三面镜子”写作提纲60例

写作技巧&#xff1a;“三面镜子”写作提纲60例 1. 用好“三面镜子” 推深做实警示教育 勤用“反光镜”以案为鉴。 善用“显微镜”以案明纪。 巧用“聚光镜”以案促改。 2. 年轻干部要用好“三面镜子” 用好“反光镜”&#xff0c;照亮基层中的“暗点” 用好“显微镜”&am…

掌握Memory Profiler技巧:识别内存问题

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、如何使用四、页面说明4.1 Java 和 Kotlin 分配…

命令模式——请求发送者与接收者解耦

1、简介 1.1、概述 在软件开发中&#xff0c;经常需要向某些对象发送请求&#xff08;调用其中的某个或某些方法&#xff09;&#xff0c;但是并不知道请求的接收者是谁&#xff0c;也不知道被请求的操作是哪个。此时&#xff0c;特别希望能够以一种松耦合的方式来设计软件&a…

十四.redis哨兵模式

redis哨兵模式 1.概述2.测试3.哨兵模式优缺点 redis哨兵模式基础是主从复制 1.概述 主从切换的技术方法&#xff1a;当主节点服务器宕机后&#xff0c;需要手动把一台从服务器切换为主服务器&#xff0c;这就需要人工干预&#xff0c;费时费力&#xff0c;还会造成一段时间内服…

【N32L40X】学习笔记13-软件IIC读写EEPROM AT24C02

AT24C02 8个字节每页,累计32个页 通讯频率MAX 400K AT24C02大小 2K 芯片地址 对于at24c02 A2A1A0 这三个引脚没有使用 写时序 由于设备在写周期中不会产生ACK恢复&#xff0c;因此这可用于确定周期何时完成&#xff08;此特性可用于最大限度地提高总线吞吐量&#xff09;…

机器学习笔记 - YOLO-NAS 最高效的目标检测算法之一

一、YOLO-NAS概述 YOLO(You Only Look Once)是一种对象检测算法,它使用深度神经网络模型,特别是卷积神经网络,来实时检测和分类对象。该算法首次在 2016 年由 Joseph Redmon、Santosh Divvala、Ross Girshick 和 Ali Farhadi 发表的论文《You Only Look Once: Unified, Re…

2023-08-05——JVM 栈

栈 stack 栈&#xff1a;数据结构 程序数据结构算法 栈&#xff1a;先进后出&#xff0c;后进先出 好比一个&#xff1a;桶 队列&#xff1a;先进先出&#xff08;FIFO &#xff1a;First Input First Out&#xff09; 好比一个&#xff1a;管道 栈&#xff1a;喝多了吐。队列…

抽象轻松JavaScript

随心所欲的数组切割与改变2.0版本 splice(开始位置&#xff0c;删除数量&#xff0c;添加内容) slice(开始位置&#xff0c;结束位置) 目的&#xff0c;上面的一串小字&#xff0c;切割与改变 切割代表删&#xff0c;改变代表增、改&#xff0c;随心所欲的切割与改变意味着不…

分布式应用:Zookeeper 集群与kafka 集群部署

目录 一、理论 1.Zookeeper 2.部署 Zookeeper 集群 3.消息队列 4.Kafka 5.部署 kafka 集群 6.FilebeatKafkaELK 二、实验 1.Zookeeper 集群部署 2.kafka集群部署 3.FilebeatKafkaELK 三、问题 1.解压文件异常 2.kafka集群建立失败 3.启动 filebeat报错 4.VIM报错…

页面技术基础-html

页面技术基础-html 环境准备&#xff1a;在JDBC中项目上完成代码定义 1. 新建一个 Module:filr->右键 -》Module -》Java-》next->名字(html_day1)->finish 2. 在 Moudle上右键-》第二个选项&#xff1a;add framework .. -> 选择JavaEE下第一个选项 Web Apllicat…

mysql高级(尚硅谷-夏磊)

目录 内容介绍 Linux下MySQL的安装与使用 Mysql逻辑架构 Mysql存储引擎 Sql预热 索引简介 内容介绍 1、Linux下MySQL的安装与使用 2、逻辑架构 3、sql预热 Linux下MySQL的安装与使用 1、docker安装docker run -d \-p 3309:3306 \-v /atguigu/mysql/mysql8/conf:/etc/my…

Xilinx A7开发板LVDS IO无输出问题解决方法

使用A7-35T FGG484的FPGA开发板bank16上的IO作为差分LVDS的输入输出&#xff0c;搭建输入输出测试工程发现LVDS可以输入、无法输出。查阅UG471&#xff0c;找到如下信息&#xff1a; 手册中已经针对A7的LVDS做了明确的应用说明&#xff1a; &#xff08;1&#xff09;HP bank上…

观察者模式——对象间的联动

1、简介 1.1、概述 在软件系统中&#xff0c;有些对象之间也存在类似交通信号灯和汽车之间的关系。一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变&#xff0c;它们之间将产生联动&#xff0c;正所谓“触一而牵百发”。为了更好地描述对象之间存在的这种一…

第一个maven项目(IDEA生成)

第一个maven项目&#xff08;IDEA生成&#xff09; 步骤1 配置Project SDK 步骤2 配置maven File->Settings搜索maven

CHI(六)独占访问

AMBA5 CHI Architecture Specification IssueF 1. overview 独占访问的原则是&#xff0c;执行独占序列的逻辑处理器&#xff08;LP&#xff09;执行以下操作&#xff1a; 对一个地址执行exclusive load。计算要存储到该位置的新值。对该地址进行exclusive store。 支持对可…

Java并发系列之二:悲观锁机制

什么是锁 在并发环境下&#xff0c;会出现多个线程对同一个资源进行争抢的情况&#xff0c;假设A线程对资源正在进行修改&#xff0c;此时B线程此时又对资源进行了修改&#xff0c;这就可能会导致数据不一致的问题。为了解决这个问题&#xff0c;很多编程语言引入了锁机制&…

RocketMQ发送消息超时异常

说明&#xff1a;在使用RocketMQ发送消息时&#xff0c;出现下面这个异常&#xff08;org.springframework.messging.MessgingException&#xff1a;sendDefaultImpl call timeout……&#xff09;&#xff1b; 解决&#xff1a;修改RocketMQ中broke.conf配置&#xff0c;添加下…

【JAVASE】多态

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈Java &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 多态 1. 概念2. 实现条件3. 重写4. 向上…