iOS知识小集 第6期(2015.10.20)

天气有点冷啊,冬天快来了~~然后貌似互联网的冬天也来了啊。阿里缩减校招名额,美团融资失败,大众点评与美团报团,百度腾讯调整招聘,一丝丝的凉意啊~~再然后就是网易邮箱密码泄漏,这又是要搞哪样?不过话说我都不记得自己是不是有网易邮箱啊。额,不知道这个冬天的第一场雪什么时候会来。不管怎样,这个冬天还是窝一窝,等来年春暖花开之时再出去浪了。

这一期的主要内容还是三点:

  1. Xcode 7Playground中导入并使用图片
  2. Playground中的字面量(Xcode 7.1)
  3. CAEmitterLayer实现粒子动画

内容不是很多,都是些小东西,主要还是一些知识碎片,这也是知识小集的出发点。所以大家就当是饭后的小点心吧。以后争取勤快一点,至少每个月出个两篇吧(what?不是说过好多次了么?)。

Xcode 7中Playground中导入并使用图片

Playground中做测试时,可能需要显示图片,这时我们就需要导入一些图片资源。在Playground中,没有像普通工程那样有个单独的Images.xcassets文件夹来存储图片,不过添加图片也是件非常简单的事情。

如果没有显示project navigator,则可以使用快捷键cmd + 0打开。默认情况下,我们可以在project navigator看到两个group。一个是Source,另一个是Resources。其中Resources这个group就是用来放置资源的(包括图片资源),如下图所示:

image
image

选中这个group,然后点击左下角的+按钮,在弹出的菜单中选择Add Files to 'Resource',然后选择要添加的文件,点确定。这样就把资源文件添加到我们的Playground了。

添加完成后,我们就可以使用这些资源了。如要显示图片,则可以使用以下代码:


let image: UIImage = UIImage(named: "test.png")!

Playground中显示如下:

image
image

另外,初始情况下,Playground的包里面并没有Resources文件夹,在我们添加资源后,会自动创建这个文件夹。然后我们可以在File Inspector中查看文件夹的具体位置,如下所示:

image
image

参考

  1. Playground Help - Adding Resources to a Playground
  2. Swift playgrounds with UIImage
  3. XCode 6: How To Add Image Assets To Your Playground

Playground中的字面量(Xcode 7.1)

Xcode 7.1新增了一项特性,让我们可以在playground代码中嵌入文件、图片和颜色的字面量。

以图片字面量为例,以往如果需要在playground使用图片资源,我们总是需要通过文件名来指定图片,如下代码所示:

let image = UIImage(named: "swift.png")

其效果如下:

image
image

而在Xcode 7.1中,我们无需在编辑器中键入"swift.png",而只需将图片从Finder或是资源中拖到我们的代码里面,就可以直接生成一个UIImage对象,如下所示:

image
image

可以看到,代码中=右侧的那个类似于小图标的东东就是一个图片字面量。是不是很酷来着?

与图片字面量类似,我们同样可以添加颜色字面量和文件字面量,添加方法可以参考Adding Color LiteralsAdding File Literals

当然,除了看上去很酷之外,这也让我们在playground中写代码时能够更快地去编辑这些资源。我们可以通过颜色选择器来插入我们想要的颜色,可以直接从Finder中将文件或图片拖到我们的代码中,而不再需要手动输入颜色值或文件名等。而如果我们想替换资源,只需要双击这些字面量就可以轻松地选择其它的资源。

字面量的表示

这里有一个问题,在代码中,这些字面量是如何表示的呢?

我们还是以图片字面量为例。选中一个图片字面量,cmd+C一下,然后找个文本编辑器,再cmd+V一下,发现拷贝出来的是如下信息:

    
[#Image(imageLiteral: "swift.png")#]

类似于一个构造器。我们再到UIImage中找找,可以看到UIImage有一个扩展,如下所示:


extension UIImage : _ImageLiteralConvertible {
    required public convenience init(imageLiteral name: String)
}

这个扩展让UIImage类实现了_ImageLiteralConvertible协议,看这命名,貌似是一个私有的协议。我们来看看它的字义,如下所示:

/// Conforming types can be initialized with image literals (e.g.
/// `[#Image(imageLiteral: "hi.png")#]`).
public protocol _ImageLiteralConvertible {
    public init(imageLiteral: String)
}

可以看到,实现这个协议的类型就可以使用图片字面量来初始化,即我们上面所看到。当然,我们没办法看到源码是怎么实现的,只能到此为止。

实际上,这些字面量会被转换成平台指定的类型,在官方的swift blog中列出了一个清单,如下所示:

image
image

还有件看起来很酷但似乎并不太实用的事是:这些字面量不但可以用在playground中,而且还有可用在工程代码中。不过之所有不太实用,是因为在工程代码中只能以纯文本的形式来展现,而不是像在playground中那样能直观的显示。这种纯文本形式即我们上面拷贝出来的信息,我们再贴一次:

    
[#Image(imageLiteral: "swift.png")#]

我们码段代码:


let image = [#Image(imageLiteral: "swift.png")#]
let imageView = UIImageView(image: image)
imageView.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
self.view.addSubview(imageView)

其效果如下所示:

image
image

从代码实践的角度来看,这种写法看上去并不是那么美啊。不过由于这种写法是与平台相关的,所以如果工程需要同时支持OSXiOStvOS,还是可以考虑用一下的。

小结

总之,在playground中使用图片、颜色、文件字面量还是一件很酷的事,它大大提高了我们使用资源的效率,同时也更加直观,用起来还是满爽的。

这里附上官方的实例:Literals.playground

参考

  1. Literals in Playgrounds
  2. Adding Image Literals
  3. Adding Color Literals
  4. Adding File Literals

CAEmitterLayer实现粒子动画

前段时间@MartinRGB做了个带粒子效果的删除单元格动画,今天问他具体的实现方式,然后他把参考的原始工程发我看了一下。于是就找到了这个:UIEffectDesignerView。是github上的一个粒子动画的开源代码。其效果如下图所示:

image
image

这个动画的实现基于CAEmitterLayer类,它继承自CALayer。这个类是Core Animation提供的用于实现一个粒子发射器系统的类。这个类主要提供了一些属性来设置粒子系统的几何特性。我们可以如下处理:

let emitter = CAEmitterLayer()
// setup the emitter metrics
emitter.emitterPosition = CGPoint(x: self.bounds.size.width / 2, y: self.bounds.height / 2)
emitter.emitterSize = self.bounds.size
// setup the emitter type and mode
let kEmitterModes = [ kCAEmitterLayerUnordered, kCAEmitterLayerAdditive, kCAEmitterLayerOldestLast, kCAEmitterLayerOldestFirst ]
emitter.emitterMode = kEmitterModes[ Int(valueFromEffect("emitterMode")) ]

_ 需要注意的就是粒子系统会被绘制到层的背影颜色及边框之上。_

当然,要想发射粒子,就需要有粒子源。一个粒子源定义了发射的粒子的方向及其它属性。在Core Animation中,使用CAEmitterCell对象来表示一个粒子源。CAEmitterCell定义了大量的属性来设置一个粒子源的特性,如粒子的显示特性(color, scale, style)、运动特性(如spin, emissionLatitude)、时间特性(如lifetime, birthRate, velocity)等。我们可以手动来设置这些值,也可以从文件中获取。在UIEffectDesignerView工程中,粒子发射器的信息是放在一个ped文件中,这个文件以JSON格式存储了粒子信息,如下所示:


{
    "latitude": 0, 
    "alphaSpeed": 0, 
    "scaleSpeed": 0, 
    "blueRange": 0.33, 
    "width": 120, 
    "texture": "....", 
    "spinRange": 0, 
    "lifetime": 5, 
    "greenSpeed": 0, 
    "aux3": null, 
    "emitterType": 0, 
    "version": 0.1, 
    "zAcceleration": 0, 
    "velocity": 100, 
    "velocityRange": 150, 
    ...
    "y": 390, 
    "aux2": null
}

我们从文件中把粒子信息读取出来放到一个字典中,然后再将值赋给一个CAEmitterCell对象,如下所示:

// create new emitter cell
let emitterCell: CAEmitterCell = CAEmitterCell()
let effect: [String: AnyObject] = loadFile(filename)
...
emitterCell.birthRate           = effect("birthRate")
emitterCell.lifetime            = effect("lifetime")
emitterCell.lifetimeRange       = effect("lifetimeRange")
emitterCell.velocity            = effect("velocity")
emitterCell.velocityRange       = effect("velocityRange")
...

之后,我们便可以把这个粒子源添加到粒子系统中,如下所示:

    
emitter.emitterCells = [ emitterCell ]

这样就可以发射粒子了。

当然对于一个粒子的特性,除了受粒子源设置的属性影响外,同样也还受粒子系统的一些属性的影响,如下代码所示:

    
emitter.scale = 0.5

其效果如下图所示:

image
image

另外,一个粒子源也可以包含一个子粒子源的数组,每个子源都可以作为一个独立的发射源。

参考

  1. UIEffectDesignerView
  2. CAEmitterLayer Class Reference
  3. CAEmitterCell Class Reference

零碎

C语言的int类型在Swift中的对应类型

一言以蔽之,C语言的int类型在Swift中的对应类型是CInt,它是Int32的一个别名。今天一哥们用Swift写了一段测试代码来调用C方法,方法中有个参数是int类型,类似于如下代码:

let str = "Hello, World!"
let a = str.characters.count
Test.test(a)        // test方法接受一个int类型的参数
// 编译器错误:Cannot convert value of type 'Distance'(aka 'Int') to expected argument type Int32

可以看到我们需要传入一个Int32类型的参数。

之所以使用Int32,是因为在C语言中,int4个字节,而Swift中的Int则依赖于平台,可能是4个字节,也可能是8个字节。嗯,这个问题是凑数的,点到为止吧。

Swift中获取类型的大小

C语言中,如果我们想获取一个变量或数据类型的大小,则可以使用sizeof函数。如下所示:

int a = 10;
printf("%lu, %lu", sizeof(int), sizeof(a));
// 输出:4,4

Swift中,也提供了相应的函数。我们可以使用sizeof来获取给定类型的大小,使用sizeofValue来获取给定值的类型的大小。如下所示:

sizeof(Int)             // 8
let c: Int = 10
sizeofValue(c)          // 8

不过,与C语言中的sizeof不同的是,Siwft中的sizeofsizeofValue不包含任何内存对齐的填充部分。如timeval结构体,在C语言中的大小是16,而在Swift中,则是12,并未包含4个填充字节。

sizeof(timeval)         // 12

不过,Swift提供了两个对应的函数,来计算经过内存对齐的类型的大小,即strideofstrideofValue,如下所示:


let time = timeval(tv_sec: 10, tv_usec: 10)

strideof(timeval)       // 16
strideofValue(time)     // 16

参考

  1. Using Swift with Cocoa and Objective-C (Swift 2)

问题:纯Playground中使用Objective-C/C代码

今天想在纯Playground中测试一下CC_MD5方法,发现没招。因为CC_MD5实际上是一个C方法,需要导入<CommonCrypto/CommonCrypto.h>头文件。这就涉及到SwiftObjective-C混编,需要创建一个桥接文件。但是纯Playground貌似并不支持这么做(搜了一下没搜着解决方法)。于是只能采取曲线救国策略,建立一个基于Swift的工程,在这里面创建桥接文件,导入头文件。然后在工程中创建一个Playground来做测试了。

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,029评论 4 62
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,517评论 25 707
  • 裁判已在看表 看台有人离席 结果即将平局 你 心怀奇迹 长传卸在脚底 晃动突入禁区 脚尖轻轻一挑 妙 球进网底 欢...
    xdoolei阅读 155评论 0 0
  • 6年前,因为《爱丽丝梦游仙境》爱上Depp,补齐了四部《加勒比海盗》,迷上了《剪刀手爱德华》里他和早已分道扬镳的W...
    蘑菇小姐Bear阅读 3,586评论 0 4
  • 曾棱角锋利无比 奈何流转尘世 因棱角过于锋利 遭受无妄之灾 自磨去棱角 收心脾性 终 成世人眼中完美之状 鹅卵 忘...
    蝎小武阅读 937评论 0 0