天氣有點冷啊安接,冬天快來了~~然后貌似互聯(lián)網(wǎng)的冬天也來了啊翔忽。阿里縮減校招名額,美團融資失敗盏檐,大眾點評與美團報團歇式,百度騰訊調整招聘,一絲絲的涼意啊~~再然后就是網(wǎng)易郵箱密碼泄漏胡野,這又是要搞哪樣材失?不過話說我都不記得自己是不是有網(wǎng)易郵箱啊。額给涕,不知道這個冬天的第一場雪什么時候會來豺憔。不管怎樣,這個冬天還是窩一窩够庙,等來年春暖花開之時再出去浪了恭应。
這一期的主要內(nèi)容還是三點:
-
Xcode 7
中Playground
中導入并使用圖片 -
Playground
中的字面量(Xcode 7.1
) -
CAEmitterLayer
實現(xiàn)粒子動畫
內(nèi)容不是很多,都是些小東西耘眨,主要還是一些知識碎片昼榛,這也是知識小集的出發(fā)點。所以大家就當是飯后的小點心吧。以后爭取勤快一點胆屿,至少每個月出個兩篇吧(what?不是說過好多次了么奥喻?)。
Xcode 7中Playground中導入并使用圖片
在Playground
中做測試時非迹,可能需要顯示圖片环鲤,這時我們就需要導入一些圖片資源。在Playground
中憎兽,沒有像普通工程那樣有個單獨的Images.xcassets
文件夾來存儲圖片冷离,不過添加圖片也是件非常簡單的事情。
如果沒有顯示project navigator
纯命,則可以使用快捷鍵cmd + 0
打開西剥。默認情況下,我們可以在project navigator
看到兩個group
亿汞。一個是Source
瞭空,另一個是Resources
。其中Resources
這個group
就是用來放置資源的(包括圖片資源)疗我,如下圖所示:

選中這個group
咆畏,然后點擊左下角的+
按鈕,在彈出的菜單中選擇Add Files to 'Resource'
碍粥,然后選擇要添加的文件鳖眼,點確定。這樣就把資源文件添加到我們的Playground
了嚼摩。
添加完成后钦讳,我們就可以使用這些資源了。如要顯示圖片枕面,則可以使用以下代碼:
let image: UIImage = UIImage(named: "test.png")!
在Playground
中顯示如下:

另外愿卒,初始情況下,Playground
的包里面并沒有Resources
文件夾潮秘,在我們添加資源后琼开,會自動創(chuàng)建這個文件夾。然后我們可以在File Inspector
中查看文件夾的具體位置枕荞,如下所示:

參考
- Playground Help - Adding Resources to a Playground
- Swift playgrounds with UIImage
- 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")
其效果如下:

而在Xcode 7.1
中辅柴,我們無需在編輯器中鍵入"swift.png"
,而只需將圖片從Finder
或是資源中拖到我們的代碼里面,就可以直接生成一個UIImage
對象碌嘀,如下所示:

可以看到涣旨,代碼中=
右側的那個類似于小圖標的東東就是一個圖片字面量。是不是很酷來著股冗?
與圖片字面量類似霹陡,我們同樣可以添加顏色字面量和文件字面量,添加方法可以參考Adding Color Literals和Adding File Literals魁瞪。
當然穆律,除了看上去很酷之外,這也讓我們在playground
中寫代碼時能夠更快地去編輯這些資源导俘。我們可以通過顏色選擇器來插入我們想要的顏色,可以直接從Finder
中將文件或圖片拖到我們的代碼中剔蹋,而不再需要手動輸入顏色值或文件名等旅薄。而如果我們想替換資源,只需要雙擊這些字面量就可以輕松地選擇其它的資源泣崩。
字面量的表示
這里有一個問題少梁,在代碼中,這些字面量是如何表示的呢矫付?
我們還是以圖片字面量為例凯沪。選中一個圖片字面量,cmd+C
一下买优,然后找個文本編輯器妨马,再cmd+V
一下,發(fā)現(xiàn)拷貝出來的是如下信息:
[#Image(imageLiteral: "swift.png")#]
類似于一個構造器杀赢。我們再到UIImage
中找找烘跺,可以看到UIImage
有一個擴展,如下所示:
extension UIImage : _ImageLiteralConvertible {
required public convenience init(imageLiteral name: String)
}
這個擴展讓UIImage
類實現(xiàn)了_ImageLiteralConvertible
協(xié)議脂崔,看這命名滤淳,貌似是一個私有的協(xié)議。我們來看看它的字義砌左,如下所示:
/// Conforming types can be initialized with image literals (e.g.
/// `[#Image(imageLiteral: "hi.png")#]`).
public protocol _ImageLiteralConvertible {
public init(imageLiteral: String)
}
可以看到脖咐,實現(xiàn)這個協(xié)議的類型就可以使用圖片字面量來初始化,即我們上面所看到汇歹。當然屁擅,我們沒辦法看到源碼是怎么實現(xiàn)的,只能到此為止秤朗。
實際上煤蹭,這些字面量會被轉換成平臺指定的類型,在官方的swift blog
中列出了一個清單,如下所示:

還有件看起來很酷但似乎并不太實用的事是:這些字面量不但可以用在playground
中硝皂,而且還有可用在工程代碼中常挚。不過之所有不太實用,是因為在工程代碼中只能以純文本的形式來展現(xiàn)稽物,而不是像在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)
其效果如下所示:

從代碼實踐的角度來看贝或,這種寫法看上去并不是那么美啊吼过。不過由于這種寫法是與平臺相關的,所以如果工程需要同時支持OSX
咪奖、iOS
和tvOS
盗忱,還是可以考慮用一下的节预。
小結
總之沼溜,在playground
中使用圖片、顏色友多、文件字面量還是一件很酷的事昧捷,它大大提高了我們使用資源的效率闲昭,同時也更加直觀,用起來還是滿爽的靡挥。
這里附上官方的實例:Literals.playground
參考
CAEmitterLayer實現(xiàn)粒子動畫
前段時間@MartinRGB做了個帶粒子效果的刪除單元格動畫序矩,今天問他具體的實現(xiàn)方式,然后他把參考的原始工程發(fā)我看了一下跋破。于是就找到了這個:UIEffectDesignerView簸淀。是github
上的一個粒子動畫的開源代碼。其效果如下圖所示:

這個動畫的實現(xiàn)基于CAEmitterLayer
類幔烛,它繼承自CALayer
啃擦。這個類是Core Animation
提供的用于實現(xiàn)一個粒子發(fā)射器系統(tǒng)的類。這個類主要提供了一些屬性來設置粒子系統(tǒng)的幾何特性饿悬。我們可以如下處理:
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")) ]
_ 需要注意的就是粒子系統(tǒng)會被繪制到層的背影顏色及邊框之上令蛉。_
當然,要想發(fā)射粒子狡恬,就需要有粒子源珠叔。一個粒子源定義了發(fā)射的粒子的方向及其它屬性。在Core Animation
中弟劲,使用CAEmitterCell
對象來表示一個粒子源祷安。CAEmitterCell
定義了大量的屬性來設置一個粒子源的特性,如粒子的顯示特性(color
, scale
, style
)兔乞、運動特性(如spin
, emissionLatitude
)汇鞭、時間特性(如lifetime
, birthRate
, velocity
)等凉唐。我們可以手動來設置這些值,也可以從文件中獲取霍骄。在UIEffectDesignerView
工程中台囱,粒子發(fā)射器的信息是放在一個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")
...
之后米间,我們便可以把這個粒子源添加到粒子系統(tǒng)中强品,如下所示:
emitter.emitterCells = [ emitterCell ]
這樣就可以發(fā)射粒子了。
當然對于一個粒子的特性屈糊,除了受粒子源設置的屬性影響外的榛,同樣也還受粒子系統(tǒng)的一些屬性的影響,如下代碼所示:
emitter.scale = 0.5
其效果如下圖所示:

另外逻锐,一個粒子源也可以包含一個子粒子源的數(shù)組困曙,每個子源都可以作為一個獨立的發(fā)射源。
參考
零碎
C語言的int類型在Swift中的對應類型
一言以蔽之谦去,C
語言的int
類型在Swift
中的對應類型是CInt
,它是Int32
的一個別名蹦哼。今天一哥們用Swift
寫了一段測試代碼來調用C
方法鳄哭,方法中有個參數(shù)是int
類型,類似于如下代碼:
let str = "Hello, World!"
let a = str.characters.count
Test.test(a) // test方法接受一個int類型的參數(shù)
// 編譯器錯誤:Cannot convert value of type 'Distance'(aka 'Int') to expected argument type Int32
可以看到我們需要傳入一個Int32
類型的參數(shù)纲熏。
之所以使用Int32
妆丘,是因為在C
語言中,int
是4
個字節(jié)局劲,而Swift
中的Int
則依賴于平臺勺拣,可能是4
個字節(jié),也可能是8
個字節(jié)鱼填。嗯药有,這個問題是湊數(shù)的,點到為止吧苹丸。
Swift中獲取類型的大小
在C
語言中愤惰,如果我們想獲取一個變量或數(shù)據(jù)類型的大小,則可以使用sizeof
函數(shù)赘理。如下所示:
int a = 10;
printf("%lu, %lu", sizeof(int), sizeof(a));
// 輸出:4,4
在Swift
中宦言,也提供了相應的函數(shù)。我們可以使用sizeof
來獲取給定類型的大小商模,使用sizeofValue
來獲取給定值的類型的大小奠旺。如下所示:
sizeof(Int) // 8
let c: Int = 10
sizeofValue(c) // 8
不過蜘澜,與C
語言中的sizeof
不同的是,Siwft
中的sizeof
與sizeofValue
不包含任何內(nèi)存對齊的填充部分响疚。如timeval
結構體鄙信,在C
語言中的大小是16
,而在Swift
中稽寒,則是12
扮碧,并未包含4
個填充字節(jié)。
sizeof(timeval) // 12
不過杏糙,Swift
提供了兩個對應的函數(shù)慎王,來計算經(jīng)過內(nèi)存對齊的類型的大小,即strideof
秘strideofValue
宏侍,如下所示:
let time = timeval(tv_sec: 10, tv_usec: 10)
strideof(timeval) // 16
strideofValue(time) // 16
參考
問題:純Playground中使用Objective-C/C代碼
今天想在純Playground
中測試一下CC_MD5
方法赖淤,發(fā)現(xiàn)沒招。因為CC_MD5
實際上是一個C
方法谅河,需要導入<CommonCrypto/CommonCrypto.h>
頭文件咱旱。這就涉及到Swift
與Objective-C
混編,需要創(chuàng)建一個橋接文件绷耍。但是純Playground
貌似并不支持這么做(搜了一下沒搜著解決方法)吐限。于是只能采取曲線救國策略,建立一個基于Swift
的工程褂始,在這里面創(chuàng)建橋接文件诸典,導入頭文件。然后在工程中創(chuàng)建一個Playground
來做測試了崎苗。