iOS 7最佳实践:一个天气App案例
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224112057_1.gif)
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224100514_1.gif)
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224100607_1.png)
- which pod
- /usr/bin/pod
- platform :ios, '7.0'
- pod 'Mantle'
- pod 'LBBlurredImage'
- pod 'TSMessages'
- pod 'ReactiveCocoa'
- $ pod install
- Analyzing dependencies
- CocoaPods 0.28.0 is available.
- Downloading dependencies
- Installing HexColors (2.2.1)
- Installing LBBlurredImage (0.1.0)
- Installing Mantle (1.3.1)
- Installing ReactiveCocoa (2.1.7)
- Installing TSMessages (0.9.4)
- Generating Pods project
- Integrating client project
- [!] From now on use `SimpleWeather.xcworkspace`.
- sjpsega注:若你之前安装过Cocoapods的话,这里安装报错的话,可以看看http://blog.cocoapods.org/Repairing-Our-Broken-Specs-Repository/ 修复问题
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224100858_1.jpg)
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224100940_1.jpg)
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224100955_1.jpg)
- 提示:您可能会注意到有一些项目生成警告。因为Cocoapods引入的项目,是由不同的开发者开发,并且不同的开发者对生成警告有不同的态度。通常,你应该可以忽略它们。只要确保没有任何编译器错误!
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224101037_1.jpg)
- - (void)viewDidLoad {
- [super viewDidLoad];
- // Remove this later
- self.view.backgroundColor = [UIColor redColor];
- }
- #import "WXController.h"
- #import <TSMessage.h>
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- // 1
- self.window.rootViewController = [[WXController alloc] init];
- self.window.backgroundColor = [UIColor whiteColor];
- [self.window makeKeyAndVisible];
- // 2
- [TSMessage setDefaultViewController: self.window.rootViewController];
- return YES;
- }
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224101145_1.jpg)
- - (UIStatusBarStyle)preferredStatusBarStyle {
- return UIStatusBarStyleLightContent;
- }
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224101234_1.jpg)
- <UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate>
- #import <LBBlurredImage/UIImageView+LBBlurredImage.h>
- @interface WXController ()
- @property (nonatomic, strong) UIImageView *backgroundImageView;
- @property (nonatomic, strong) UIImageView *blurredImageView;
- @property (nonatomic, strong) UITableView *tableView;
- @property (nonatomic, assign) CGFloat screenHeight;
- @end
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224101336_1.jpg)
- // 1
- self.screenHeight = [UIScreen mainScreen].bounds.size.height;
- UIImage *background = [UIImage imageNamed:@"bg"];
- // 2
- self.backgroundImageView = [[UIImageView alloc] initWithImage:background];
- self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill;
- [self.view addSubview:self.backgroundImageView];
- // 3
- self.blurredImageView = [[UIImageView alloc] init];
- self.blurredImageView.contentMode = UIViewContentModeScaleAspectFill;
- self.blurredImageView.alpha = 0;
- [self.blurredImageView setImageToBlur:background blurRadius:10 completionBlock:nil];
- [self.view addSubview:self.blurredImageView];
- // 4
- self.tableView = [[UITableView alloc] init];
- self.tableView.backgroundColor = [UIColor clearColor];
- self.tableView.delegate = self;
- self.tableView.dataSource = self;
- self.tableView.separatorColor = [UIColor colorWithWhite:1 alpha:0.2];
- self.tableView.pagingEnabled = YES;
- [self.view addSubview:self.tableView];
- // 1
- #pragma mark - UITableViewDataSource
- // 2
- - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return 2;
- }
- - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- // TODO: Return count of forecast
- return 0;
- }
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
- static NSString *CellIdentifier = @"CellIdentifier";
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
- if (! cell) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
- }
- // 3
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- cell.backgroundColor = [UIColor colorWithWhite:0 alpha:0.2];
- cell.textLabel.textColor = [UIColor whiteColor];
- cell.detailTextLabel.textColor = [UIColor whiteColor];
- // TODO: Setup the cell
- return cell;
- }
- #pragma mark - UITableViewDelegate
- - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
- // TODO: Determine cell height based on screen
- return 44;
- }
- 注意:使用格式化的注释 // TODO:可以帮助Xcode找到需要以后完成的代码。你还可以使用 Show Document Items(Control-6)来查看TODO项。
- - (void)viewWillLayoutSubviews {
- [super viewWillLayoutSubviews];
- CGRect bounds = self.view.bounds;
- self.backgroundImageView.frame = bounds;
- self.blurredImageView.frame = bounds;
- self.tableView.frame = bounds;
- }
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224101533_1.jpg)
- // 1
- CGRect headerFrame = [UIScreen mainScreen].bounds;
- // 2
- CGFloat inset = 20;
- // 3
- CGFloat temperatureHeight = 110;
- CGFloat hiloHeight = 40;
- CGFloat iconHeight = 30;
- // 4
- CGRect hiloFrame = CGRectMake(inset,
- headerFrame.size.height - hiloHeight,
- headerFrame.size.width - (2 * inset),
- hiloHeight);
- CGRect temperatureFrame = CGRectMake(inset,
- headerFrame.size.height - (temperatureHeight + hiloHeight),
- headerFrame.size.width - (2 * inset),
- temperatureHeight);
- CGRect iconFrame = CGRectMake(inset,
- temperatureFrame.origin.y - iconHeight,
- iconHeight,
- iconHeight);
- // 5
- CGRect conditionsFrame = iconFrame;
- conditionsFrame.size.width = self.view.bounds.size.width - (((2 * inset) + iconHeight) + 10);
- conditionsFrame.origin.x = iconFrame.origin.x + (iconHeight + 10);
- // 1
- UIView *header = [[UIView alloc] initWithFrame:headerFrame];
- header.backgroundColor = [UIColor clearColor];
- self.tableView.tableHeaderView = header;
- // 2
- // bottom left
- UILabel *temperatureLabel = [[UILabel alloc] initWithFrame:temperatureFrame];
- temperatureLabel.backgroundColor = [UIColor clearColor];
- temperatureLabel.textColor = [UIColor whiteColor];
- temperatureLabel.text = @"0°";
- temperatureLabel.font = [UIFont fontWithName:@"HelveticaNeue-UltraLight" size:120];
- [header addSubview:temperatureLabel];
- // bottom left
- UILabel *hiloLabel = [[UILabel alloc] initWithFrame:hiloFrame];
- hiloLabel.backgroundColor = [UIColor clearColor];
- hiloLabel.textColor = [UIColor whiteColor];
- hiloLabel.text = @"0° / 0°";
- hiloLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:28];
- [header addSubview:hiloLabel];
- // top
- UILabel *cityLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, 30)];
- cityLabel.backgroundColor = [UIColor clearColor];
- cityLabel.textColor = [UIColor whiteColor];
- cityLabel.text = @"Loading...";
- cityLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:18];
- cityLabel.textAlignment = NSTextAlignmentCenter;
- [header addSubview:cityLabel];
- UILabel *conditionsLabel = [[UILabel alloc] initWithFrame:conditionsFrame];
- conditionsLabel.backgroundColor = [UIColor clearColor];
- conditionsLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:18];
- conditionsLabel.textColor = [UIColor whiteColor];
- [header addSubview:conditionsLabel];
- // 3
- // bottom left
- UIImageView *iconView = [[UIImageView alloc] initWithFrame:iconFrame];
- iconView.contentMode = UIViewContentModeScaleAspectFit;
- iconView.backgroundColor = [UIColor clearColor];
- [header addSubview:iconView];
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224101818_1.jpg)
- // 1
- @interface WXCondition : MTLModel <MTLJSONSerializing>
- // 2
- @property (nonatomic, strong) NSDate *date;
- @property (nonatomic, strong) NSNumber *humidity;
- @property (nonatomic, strong) NSNumber *temperature;
- @property (nonatomic, strong) NSNumber *tempHigh;
- @property (nonatomic, strong) NSNumber *tempLow;
- @property (nonatomic, strong) NSString *locationName;
- @property (nonatomic, strong) NSDate *sunrise;
- @property (nonatomic, strong) NSDate *sunset;
- @property (nonatomic, strong) NSString *conditionDescription;
- @property (nonatomic, strong) NSString *condition;
- @property (nonatomic, strong) NSNumber *windBearing;
- @property (nonatomic, strong) NSNumber *windSpeed;
- @property (nonatomic, strong) NSString *icon;
- // 3
- - (NSString *)imageName;
- @end
- + (NSDictionary *)imageMap {
- // 1
- static NSDictionary *_imageMap = nil;
- if (! _imageMap) {
- // 2
- _imageMap = @{
- @"01d" : @"weather-clear",
- @"02d" : @"weather-few",
- @"03d" : @"weather-few",
- @"04d" : @"weather-broken",
- @"09d" : @"weather-shower",
- @"10d" : @"weather-rain",
- @"11d" : @"weather-tstorm",
- @"13d" : @"weather-snow",
- @"50d" : @"weather-mist",
- @"01n" : @"weather-moon",
- @"02n" : @"weather-few-night",
- @"03n" : @"weather-few-night",
- @"04n" : @"weather-broken",
- @"09n" : @"weather-shower",
- @"10n" : @"weather-rain-night",
- @"11n" : @"weather-tstorm",
- @"13n" : @"weather-snow",
- @"50n" : @"weather-mist",
- };
- }
- return _imageMap;
- }
- // 3
- - (NSString *)imageName {
- return [WXCondition imageMap][self.icon];
- }
- {
- "dt": 1384279857,
- "id": 5391959,
- "main": {
- "humidity": 69,
- "pressure": 1025,
- "temp": 62.29,
- "temp_max": 69.01,
- "temp_min": 57.2
- },
- "name": "San Francisco",
- "weather": [
- {
- "description": "haze",
- "icon": "50d",
- "id": 721,
- "main": "Haze"
- }
- ]
- }
- + (NSDictionary *)JSONKeyPathsByPropertyKey {
- return @{
- @"date": @"dt",
- @"locationName": @"name",
- @"humidity": @"main.humidity",
- @"temperature": @"main.temp",
- @"tempHigh": @"main.temp_max",
- @"tempLow": @"main.temp_min",
- @"sunrise": @"sys.sunrise",
- @"sunset": @"sys.sunset",
- @"conditionDescription": @"weather.description",
- @"condition": @"weather.main",
- @"icon": @"weather.icon",
- @"windBearing": @"wind.deg",
- @"windSpeed": @"wind.speed"
- };
- }
- + (NSValueTransformer *)dateJSONTransformer {
- // 1
- return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSString *str) {
- return [NSDate dateWithTimeIntervalSince1970:str.floatValue];
- } reverseBlock:^(NSDate *date) {
- return [NSString stringWithFormat:@"%f",[date timeIntervalSince1970]];
- }];
- }
- // 2
- + (NSValueTransformer *)sunriseJSONTransformer {
- return [self dateJSONTransformer];
- }
- + (NSValueTransformer *)sunsetJSONTransformer {
- return [self dateJSONTransformer];
- }
- + (NSValueTransformer *)conditionDescriptionJSONTransformer {
- return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSArray *values) {
- return [values firstObject];
- } reverseBlock:^(NSString *str) {
- return @[str];
- }];
- }
- + (NSValueTransformer *)conditionJSONTransformer {
- return [self conditionDescriptionJSONTransformer];
- }
- + (NSValueTransformer *)iconJSONTransformer {
- return [self conditionDescriptionJSONTransformer];
- }
- #define MPS_TO_MPH 2.23694f
- + (NSValueTransformer *)windSpeedJSONTransformer {
- return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSNumber *num) {
- return @(num.floatValue*MPS_TO_MPH);
- } reverseBlock:^(NSNumber *speed) {
- return @(speed.floatValue/MPS_TO_MPH);
- }];
- }
- // current
- "main": {
- "grnd_level": 1021.87,
- "humidity": 64,
- "pressure": 1021.87,
- "sea_level": 1030.6,
- "temp": 58.09,
- "temp_max": 58.09,
- "temp_min": 58.09
- }
- // daily forecast
- "temp": {
- "day": 58.14,
- "eve": 58.14,
- "max": 58.14,
- "min": 57.18,
- "morn": 58.14,
- "night": 57.18
- }
- + (NSDictionary *)JSONKeyPathsByPropertyKey {
- // 1
- NSMutableDictionary *paths = [[super JSONKeyPathsByPropertyKey] mutableCopy];
- // 2
- paths[@"tempHigh"] = @"temp.max";
- paths[@"tempLow"] = @"temp.min";
- // 3
- return paths;
- }
![](http://www.cocoachina.com/cms/uploads/allimg/140224/4196_140224102251_1.jpg)
iOS 7最佳实践:一个天气App案例相关推荐
- iOS 7 最佳实践;一个天气应用: Part 1/2
为什么80%的码农都做不了架构师?>>> 每个开发者都有他们自己开发一个应用的好方法?一些开发者使用Auto-Layout,一些开发者使用图标算法,甚至一些开发者喜欢用Vim编 ...
- iOS7最佳实践:一个天气App案例
注:本文译自: raywenderlich ios-7-best-practices-part-1 ,去除了跟主题无关的寒暄部分. 欢迎转载,保持署名 在这个两部分的系列教程中,您将探索如何使用以下工 ...
- 一个天气App案例(一)
2019独角兽企业重金招聘Python工程师标准>>> 原文:raywenderlich ios-7-best-practices-part-1 翻译:http://www.coco ...
- 开源一个天气APP Build with React Native
About Github 断断续续花了几天的时间,利用网上开放的小米天气接口,基于React native 写了一个天气APP.App store 在审核中.设计能力有限,天气动画只加了两个,AE导出 ...
- iOS图像最佳实践总结
1. 前言 2018 WWDC 苹果官方给出了关于iOS图像处理的最佳实践,本文主要是就官方文档进行分析总结以及较为全面的拓展延伸. 官方文档:Image and Graphics Best Prac ...
- 用android制作一个记事本app_用扁平化呈现一个天气APP
作为当下最火的设计风格之一,扁平化设计其实是一种简约的Ul 设计理念,现被广泛应用于图形用户界面上,在图形材料,例如海报,艺术作品,指导文档,各类出版物等方面尤为常用. 今天为大家带来了我最近的扁平 ...
- flutter天气_牛笔!自己用Flutter撸一个天气APP
这是一款简约风格的 flutter 天气项目,提供实时.多日.24 小时.台风路径以及生活指数等服务,支持定位.删除.搜索等操作. 下图为主页效果: 开始 本身作为天气 APP,自定义绘制自然少不了, ...
- flutter offset_牛笔!自己用Flutter撸一个天气APP
这是一款简约风格的 flutter 天气项目,提供实时.多日.24 小时.台风路径以及生活指数等服务,支持定位.删除.搜索等操作. 下图为主页效果: 开始 本身作为天气 APP,自定义绘制自然少不了, ...
- 碎片的最佳实践——一个简易版的新闻应用
现在你已经将关于碎片的重要知识点都掌握得差不多了,不过在灵活运用方面可能还有些欠缺,因此又该进入最佳实践环节了. 前面有提到过,碎片很多时候都是在平板开发当中使用的,主要是为了解决屏幕空间不能充分利用 ...
最新文章
- .net 怎么循环得到数组里的值_提升ML.NET模型的准确性
- UESTC 1698 The Game
- sublime配置python3环境_【env】Sublime配置Python3开发环境
- 微服务技术方案:Spring Cloud 从入门到实战
- (转)学习密度与专注力
- dram sram利用 利用_使用量子力学技术的新型超低功耗存储器或将取代DRAM和Flash...
- django-后台管理-表显示相关
- network怎么断点调试_pycharm 调试一些小技巧
- mysql procedure
- C#的百度地图开发(一)发起HTTP请求
- POJ NOI0105-42 画矩形
- linux下检查是否安装过某软件包
- latex 引用硕士论文、博士论文 bibtex格式
- 6010dn 华为 组网 胖ap_家庭网络AC+AP升级改造记录
- 如何转换视频格式?推荐这3款视频格式转换工具
- 城市智慧排水系统导论
- 轻松拿到国外主流设计风格的图片素材
- python数据汇总_Python,将数据框中的每日数据汇总到每月和每季度
- 程序人生 - 2020年杭州市积分入学实施办法权威解读
- d作者d语言中组件式编程
热门文章
- Androidproject师进阶之路 :《Android开发进阶:从小工到专家》上市啦!
- java全拼,Java获取汉字全拼和首拼
- 数据的黑暗陷阱是什么?——你想要一匹更快的马,还是一辆汽车?
- allegro Shape has connect lines attached 问题解决办法
- 6-2 指针与数组-矩阵的各列求和分数 10 本题要求实现一个函数,求一个n (小于10)行7列的二维数组各列的和。将各列和存放在一个至少7个单元的一维数组中。函数接口定义:
- gms签名不一致_云浮【签名墙】攻略
- linux服务器安装gmt,linux GMT简易安装
- 关注中国IT产业的明天 (转)
- using the Connector/J connection property 'autoReconnect=true' to avoid this problem
- Xilinx FPGA引脚官网以及导入Excel编辑