[iOS 10 day by day] Day 7:Measurement

在iPhone7发布之后,令人兴奋的事情已经尘埃落定,现在是时候继续看看iOS10提供的新特性
这一周我们将要看看新的Measurement API:the Foundation framework的新部分。从表面上看,它看起来并不是都那么兴奋:它提供了一种在计量单位间转化的方式就像公里和英里。

然而,当你仔细思考它,我们花费了极多的时间去转化值。这可能发生在由于你有角度,但是你所用来旋转视图所用的API要求用弧度。可选择的,可能因为你的应用用英里计算距离,但是你需要为了那些更喜欢用公里单位的用户去转换成公里单位。
在iOS10之前,你可能有创造自己的函数去转换值乘其它的单位或者用外部库。现在苹果已经为你提供了有很大操控提升的API,所以让我们看看它到底能做什么。

基础 The Basics
This post uses Swift 3 released as part of the Xcode 8 GM build.
我们用测量模型去创造我们的量度用特殊的维度。你可以把“dimension”当作一个有关联并且可以相互转换的单位组,比如克可以转变成千克或者也能再次返回。每一个dimension有它自己的基础单位,而其它的单位就有了其相反的定义。像容积的基本单位是公升,一毫升被定义为0.001公升。

Creating Our Measurement
简单的开始,假设我有一品脱的牛奶而且想知道它有多少毫升,像这样:

let milk = Measurement(value: 1, unit: UnitVolume.imperialPints)
milk.converted(to: .liters)
// prints out 0.568261 L

这是很简单的。一旦我们凭借单位dimension定义了我们的量度,我们可以
合适的转换成dimension的其它单位。我们自动检查获取milk变量的类型是Measurement<UnitVolume>。它做了完美的表现,令我们可以合适的在这个组中转换成其它的值。毕竟,我们如何才能转换一公升的水成一公里。

Operators
Measurement API 支持运算符操作使用。
如果我们现在想要5品脱的牛奶,我们可以这样做

let fivePints = milk * 5

这个返回了新的量度,因此我们可以依次转换成其它的单位。

fivePints.converted(to: .cups)
// Prints 11.8387708333333 cup

你可以注意到当我们在playground使用,或者打印出Measurement,我们获取了附加的单位符号。
当然,乘法不是我们仅可用的操作符。其它的,我们有相等:

let kms = Measurement(value: 5, unit: UnitLength.kilometers)
let meters = Measurement(value: 5000, unit: UnitLength.meters)
kms == meters // true

和加法:

kms + meters // 10000.0 m
Formatters

早先我提到的我们可能想去展现不同的单位在不同的地方。
伴随着新的Measurement API,苹果也提供了MeasurementFormatter,一个添加了个在转化成字符串之前格式化量度的能力。

默认的,the measurement formatter将会使用用户当前的区域。我们将会手动的改变去看看当我们想去输出在两个城市间的距离时发生什么:

let newcastleToLondon = Measurement(value: 248, unit:     UnitLength.miles)

let formatter = MeasurementFormatter()
formatter.locale = Locale(identifier: "fr")
formatter.string(from: newcastleToLondon) // Prints 399,166 km

formatter.locale = Locale(identifier: "en_GB")
formatter.string(from: newcastleToLondon) // Prints 248 mi

好的!我们解决所有这些但是几乎不需要我们自己做任何工作。

Project
我们已经快速看了这个API的基础用法,因此让我们对它做点有意思的事情。
我们将会创造一个风力涡轮,伴随着与能被滑块所调校的风速相比例旋转的刀片。
这个涡轮相当于一个uiview的子类。它被添加到UIViewControllerview上,并伴随着其它的基础UI元素:这个滑块调整风速而且label将会用米每秒(m/s)和英里每小时(mph)来输出风速。如果你想在playground中完整的查看,请到github上自由浏览。
我们将会集中在使用Measurement API的部分上:开始时,当滑块的值改变时展现风速在label上:

 func handleWindSpeedChange(slider: UISlider) {
 let windSpeed = Measurement(value: Double(slider.value), unit: UnitSpeed.metersPerSecond)

 let milesPerHour = windSpeed.converted(to: .milesPerHour)

 windSpeedLabel.text = "Wind speed: \(windSpeed) (\(milesPerHour))"

}
我们的label就像下面这样

未转化的label.png

哇哦!我们不需要这么精确,对于我们简单的demo来说。有时我们展现了太多的小数以至于我们不能看见我们按照英里每小时的值。我们可以解决这个依靠我们先前简要提到的MeasurementFormatter

let windSpeed = Measurement(value: Double(slider.value), unit:   UnitSpeed.metersPerSecond)

let measurementFormatter: MeasurementFormatter = {
let formatter = MeasurementFormatter()
formatter.unitOptions = .providedUnit
let numberFormatter = NumberFormatter()
numberFormatter.minimumIntegerDigits = 1
numberFormatter.minimumFractionDigits = 1
numberFormatter.maximumFractionDigits = 1
formatter.numberFormatter = numberFormatter

return formatter
}()

let metersPerSecond = measurementFormatter.string(from: windSpeed)
let milesPerHour = measurementFormatter.string(from:        windSpeed.converted(to: .milesPerHour))

windSpeedLabel.text = "Wind speed: \(metersPerSecond) (\(milesPerHour))"

我们创建我们的formatter并且要求它使用特定的unitProvided。这个防止the formatter忽略我们所期望的单位并且输出测试项目接受器tit (test item taker) 觉得最合适的值。对于我,若没有设置这个值,这个测试项目接受器tit (test item taker) 将会导致我们的量度都按照英里每小时输出。
The measurement formatter它自己包含了其它能够允许我们去格式化数值部分的量度的formatter(feels a bit like formatter-ception!)。我们要求这个数字仅展现一个小数。
最后,我们需要去用formatter 去取出string构成我们的m/s和英里每小时量度。

转化了的Labels.png

像一点可见的反馈,我们想去增加涡轮旋转的频率当风速增加时(注意,这些值仅仅是为了教育的目的,而且完全没有从风里获取能量的物理学基础)。
这个TurbineView控制了动画,但是我们需要去提供每秒刀片旋转的角度。你可能定义了一个在类里的属性,就像下面这样:

 /// The angle the blades rotate per second, in radians.
 public var bladeRotationPerSecond: Double

这是OK的并且遵循了苹果的API ,角度被弧度所提供。然而你怎么去阻止那些提供这些值时使用角度的用户 。你可能会说:“那时应该去读说明文档”。
这个参数可能有一些优点,然而假使这个属性没有任何说明会怎样?它也会是一个相当简单的错,对于大多数所习惯思考度数的角度的我们。
我们如何使用Measurement,限制仅仅接受有关角度的单位?这个
我们可以允许用户提供任何他们觉得最舒服的角度并且在内部转化成任何我们需要的值。听起来很棒,让我们给出一段:

// TurbineView property
public var bladeRotationPerSecond: Measurement<UnitAngle> =    Measurement(value: 0, unit: UnitAngle.degrees) {
didSet {
  rotate()
}

}

在我们的视图控制器我们可以决定每秒的循环用以下的代码:

fun calculateTurbineRotation() {
// If we assume max value of slider = 1 rotation per second
let ratio = windSpeedSlider.value / windSpeedSlider.maximumValue

let fullRotation = Measurement(value: 360, unit: UnitAngle.degrees)

let rotationAnglePerSecond = fullRotation * Double(ratio)

turbine.bladeRotationPerSecond = rotationAnglePerSecond

}

我们可以用我们觉得最舒服的角度单位 --我选择了角度。那之后我们使用基于当前的风速来容易的乘法操作去获取旋转的角度(如果滑块值为0,那速率将会是0/40=0,反之在数值范围的最后如果滑块的值为40那么速率将会是40/40=1)。
在这我们有了我们自己美丽的风力涡轮。

原文地址:[iOS 10 Day by Day :: Day 7 :: Measurement](https://www.shinobicontrols.com/blog/ios-10-day-by-day-day-7-measurement)
原作者:Sam Burnstone @sam_burnstone
ShinobiControls 官网:ShinobiControls.com twitter : @shinobicontrols
译者:simpleton king

看了戴仓薯的daybyday文章,突然就想自己也翻一篇,第一次翻译文章,如果有什么翻的不好的地方,敬请指正。之前的daybyday可以到戴仓薯的文集(//www.greatytc.com/notebooks/5278512/latest) 浏览。
顺便求个帮助,大家iOS10下面canlebypruduce的resumedata有出问题么 ?导致不能继续重新下载。
查了下stackoverflow,有说是apple的bug。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,565评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,021评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,003评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,015评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,020评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,856评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,178评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,824评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,264评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,788评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,913评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,535评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,130评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,102评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,334评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,298评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,622评论 2 343

推荐阅读更多精彩内容

  • 《iOS 10 day by day》是 shinobicontrols 公司编写的系列博客,介绍开发者需要了解的...
    戴仓薯阅读 1,322评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,123评论 29 470
  • 天一丹走在又冷又黑的小巷,风衣在黑夜中嗦嗦作响,黄昏在世界的另一边,韩胡晓甩着双手,慢悠悠的走在在三三两两有情人...
    墨迹哼出阅读 178评论 0 1
  • 今年的夏天,好像比往年来的更早一些。 他穿着件白色T恤,黑色阿迪短裤,白色鞋帮已经有些泛黄的匡威布鞋。 为了躲避中...
    用屁股思考2017阅读 315评论 0 0