作者:Yari D’areglia,原文链接,原文日期:2017-01-03
译者:SketchK;校对:Cee;定稿:CMB

在我看来,3D Touch 是能够追踪用户按压屏幕力度、并且是 iOS 的触碰处理中最有意思且未被充分挖掘的一个能力特性。

通过这个教程,我们会创建一个自定义的按钮,并且要求用户通过 3D Touch 操作进行确认。如果用户的设备不支持 3D Touch,控件对用户的处理也会回退到备选方案。下面是预览视频,它能够让你快速了解这个自定义控件是如何工作的:





  1. 当用户开始点击屏幕时,一个圆形的进度条就会跟踪用户按压屏幕的力度。用户按压屏幕的力度会影响圆形视图填充进度,按得越用力,圆就被填充得越多(稍后我会展示在不支持 3D Touch 的设备上模拟该行为)。

  2. 当圆形被填充满的时候,它会变成一个处于激活状态的按钮,圆形进度条里的标签内容会变成 “OK” 且颜色变成绿色,这暗示着当前操作可以被确认。此时用户可以通过向上滑动手指并在圆圈上松开手指的方式来确认此操作。

通常,我们会通过弹窗的方式来询问用户是否想进行一个删除操作。我很乐意做一些 UX 交互方面的尝试,而且我认为 3D Touch 这种新的交互方式可以很好的替代原有的 “标准” 交互流程。你真的应该在一个实体机上体验一下 3D Touch,马上你就会了解到交互的便利性。😀

阅读全文

作者:Ole Begemann,原文链接,原文日期:2017-03-06
译者:Cwift;校对:numbbbbb;定稿:CMB

假设你有一个 Swift 的枚举:

enum Expression {
case number(Double)
case string(String)
}

你希望它遵守 Equatable 协议。由于该枚举具有关联值,必须手动添加,所以需要实现 == 函数

extension Expression: Equatable {
static func ==(lhs: Expression, rhs: Expression)
-> Bool {
switch (lhs, rhs) {
case let (.number(l), .number(r)): return l == r
case let (.string(l), .string(r)): return l == r
default: return false
}
}
}

这里处理了参数类型相同的两种情况,比较类型不同时会执行 default case 并返回 false。这种做法简单直接,也没错:

Expression.number(1) == .number(1) // → true
Expression.number(1) == .string("a") // → false

阅读全文

作者:Ole Begemann,原文链接,原文日期:2016-12-30
译者:Cwift;校对:walkingway;定稿:CMB

本周在 Swift 进化 板块,有一个有趣的(且争论很久的)讨论。 有人建议在 Swift 标准库中添加一个名为 DefaultConstructible 的协议,其唯一的要求是提供一个无参数的构造器:

protocol DefaultConstructible {
init()
}

换个说法,用协议的方式规范以下概念:你可以创建某种类型的“默认”值,或者说当没有附加信息时也能得到一个遵守协议的实例。

有一些人,比如 Xiaodi WuDave Abrahams,提出了一些非常好的论据来反对这个观点。在这里我再次重复一次这些观点,因为我觉得相比这个具体的话题,他们所讨论的内容有着更加广泛的意义。

阅读全文

作者:Soroush Khanlou,原文链接,原文日期:2016-10-25
译者:wiilen;校对:Cwift;定稿:CMB

要使用 NSCoding,必须遵循 NSObjectProtocol 这个类协议,因此结构体无法使用。如果我们想对某些数据进行编码,最简单的方式是将它们作为一个类来实现,并且继承自 NSObject

我找到了一种优雅的方式来将结构体包在 NSCoding 的容器中,存储时也不会让人觉得小题大做。用 Coordinate 举个例子:

阅读全文

作者:uraimo,原文链接,原文日期:2017-02-05
译者:pmst;校对:Yake;定稿:CMB

有人建议我写一个小型语言解释器,如果是 LISP 那就更完美了。作为一名程序员,这是你职业生涯必须经历的事情之一,也是一次让你大开眼界的经历:你会对日常工作中的工具产生新的见解,那些令人望而生畏的概念也会被慢慢掀开神秘的面纱。

本文中,我们基于 1978 年 John McCarthy 发表的 A Micro-Manual For Lisp - Not The Whole Thruth 文章,实现一个小型 LISP 解释器,麻雀虽小但五脏俱全,这里主要利用 Swift 框架来对一些包含 LISP 符号表达式的字符串解释。

我们最终会使用解释器来构建一个简单的 REPL (Read-Eval-Print-Loop) 程序,它将交互地执行语句并打印出求值结果。我们还实现了探究解释器的一个 Playground 。

本文将手把手教你直至完成属于你的 LISP 解释器,这将是一次难忘的周末计划。选择跟着一起实现或只是阅读介绍取决于你的心情,当然你也可以参考本文的实现,构建你独有的解释器。

下图显示了我们将要建造的总体设计:

阅读全文

作者:Ole Begemann,原文链接,原文日期:2017-02-07
译者:Cwift;校对:walkingway;定稿:CMB

本系列的其他文章:
(1)Dictionary and Set
(2)String.CharacterView(本文)

上一篇文章 中,我讨论了为什么 Set 和 Dictionary 不能遵守 MutableCollection 和 RangeReplaceableCollection。今天轮到 String.CharacterView 了。

CharacterView 遵守了 RangeReplaceableCollection,但不能遵守 MutableCollection。这是为什么呢?字符串明显是可变的; 从逻辑来看它应该遵守 MutableCollection 协议。我们需要再次回过头来考虑下协议的语义

MutableCollection 的文档制定了以下要求:

MutableCollection 协议允许更改集合中元素的值,但不允许更改集合本身的长度…
在 MutableCollection 实例的某个下标位置保存的值,之后必须可以在同一位置访问。也就是说,对于可变集合实例 a,索引 i 和值 x,以下代码示例中的两组赋值必须是等价的:

a[i] = x
let y = a[i]
// 必须等同于
a[i] = x
let y = x

阅读全文

作者:Nick Hanan,原文链接,原文日期:2016-03-17
译者:BigbigChai;校对:walkingway;定稿:CMB

许多应用程序都有访问文件的需求。也许是应用 bundle 或文件系统的文件,又或许是网上的资源。在代码里需要调用某些方法来指向这些文件。对于 Apple 平台而言,基本上只有两个选择:使用 String 或 NSURL。

使用过地址栏或任何终端的话,Swift 字符串将是一个非常容易理解的选择。我的意思是,所有的文本都是在地址栏的,对吧?Cocoa 和 Cocoa Touch SDK 中一些较旧的 API 都接收 NSURL 和字符串(通常在这些 API 中称为“路径”)作为参数,但是都越来越朝着只使用 NSURL 的方向发展。和 String 路径相比,NSURL 有许多优点,最明显的是可以访问 URL 各个部分的属性,而不必另外编写代码来从路径的字符串解析出这些组件。

请继续关注如何在 Swift 应用程序中学习创建和使用 NSURL。

阅读全文

作者:Andyy Hope,原文链接,原文日期:2016-04-14
译者:SketchK;校对:Crystal Sun;定稿:CMB

时尚日志,由你做主

之前的文章中,我们讨论了在输出日志中使用 emojis 的好处,它可以帮助我们更好的去消化和吸收海量的信息。不过我提供的实现方式并不怎么样,估计你也不会想把这些东技术用到自己的代码中去。

不管怎么样,我还是会遵守之前的约定继续讨论这个话题,向你展示如何使用 emojis 来实现输出日志的功能,而你只需在 print 函数上再多花费一点儿工夫。

阅读全文

作者:Erica Sadun,原文链接,原文日期:2017-01-24
译者:星夜暮晨;校对:Crystal Sun;定稿:CMB

久而久之,Swift 发展出一种别具一格的专用语法——即一组与其他语言相差甚远的基本惯用语法 (core idioms)。许多来自 Objective-C、Ruby、Java、Python 等等语言的开发者纷纷投向 Swift 的麾下。数日前,Nicholas T Chambers 让我帮他来磨练这门新习得的语言。他通过将 Ruby 代码移植为 Swift 的方式,来构建自己基本的编程技能。他所移植的代码是这样的:

阅读全文

作者:Soroush Khanlou,原文链接,原文日期:2017-01-04
译者:Cwift;校对:walkingway;定稿:CMB

当触发网络请求时,通常会引发许多副作用。然而,副作用对于系统的可测试性来说就是一剂毒药,并且可能会因应用程序和请求的不同而出现差异性。如果我们创建一个系统用来容纳这些副作用的组合,就可以提高系统的可测试性和其他特性。

阅读全文

作者:Erica Sadun,原文链接,原文日期:2017-01-31
译者:星夜暮晨;校对:Crystal Sun;定稿:CMB

本挑战由 Mike Ash 提供,如下所示,假设有这样一个枚举:

enum Enum {
case foo(Int)
case bar(String)
case qux(Int)
}

这些枚举还组成了的一个数组:

let items: [Enum] = [.foo(1), .bar("hi"), .foo(2)]

需要对数组进行筛选 (filter),挑选并创建只包含某种枚举值 (case) 的新数组。麻烦的是,Swift 没有一种类似 ==~= 的操作符,可以让我们忽略枚举的关联值:

// 不起作用
let filtered = items.filter({ $0 == .foo })

那么应该怎么办呢?

阅读全文

作者:Soroush Khanlou,原文链接,原文日期:2017-01-12
译者:Cwift;校对:walkingway;定稿:CMB

我经常观察一个类型的实例变量,这样我就可以更深入地理解这个类型设计的初衷。一旦你知晓该类型的底层结构,它的用法也就随之浮出水面了。反之亦然:如果你没看过一个对象内部成员的布局情况,那么不可能准确把握该对象的功能。这种情况对于苹果的闭源类型尤其明显。

阅读全文

作者:Ole Begemann,原文链接,原文日期:2016-12-07
译者:Cwift;校对:walkingway;定稿:CMB

你遇到过这个问题吗?想要在 UI 中显示一个可选值或将其打印到控制台以便调试,但是你不喜欢可选值转成字符串的默认格式:Optional(…)nil。比如:

var someValue: Int? = 5
print("The value is \(someValue)")
// → "The value is Optional(5)"
someValue = nil
print("The value is \(someValue)")
// → "The value is nil"

阅读全文

作者:Ole Begemann,原文链接,原文日期:2017-01-09
译者:Cwift;校对:walkingway;定稿:CMB

Swift Talk episode 31 上,Chris 和 Florian 展示了一种针对 Swift 中可变的嵌套异构字典的解决方案,这种字典是 [String:Any] 类型的。这是一个有趣的讨论,我鼓励你看看原视频或者阅读这篇优秀的文字记录。

我为准备这期对话节目做了点微小的贡献,不过围绕这个问题所进行的一些实验代码视频并没有提到,所以我想在这里展示给你。

阅读全文