2017年2月12日 星期日

iOS筆記:Core Animation

Core Animation:

Core Animation 是在 iOS 上負責一般 UI 繪圖與動畫的 framework. 要注意的是, Core Animation是直接作用在CALayer上, 而非UIView. 至於一個 view 呈現出來的外觀,在 iOS 上,UIView 的外觀呈現,也都是由 Core Animation 實作。我們看到的 UIView 的樣子,其實是裡頭的 CALayer 的樣子。

每個 UIView,都是屬於自己專屬的 CALayer 物件的 delegate,當我們要重繪某個 view 的內容時,其實是叫 CALayer 重繪,重繪 CALayer 時會呼叫到 CALayer 的-drawInContext:,在這個 method 中,CALayer 可以自己決定怎麼繪製內容,或是去問 delegate 該怎麼畫,而去問了 CALayer delegate 的 -drawLayer:inContext:。

在 UIView 的 -drawLayer:inContext: 的實作中,便呼叫了 drawRect:,因此, drawRect: 繪製的內容,放到 CALayer 上。

範例可以參考reference!

Reference:
1. https://zonble.gitbooks.io/kkbox-ios-dev/content/core_animation/index.html
2. http://www.bkjia.com/IOSjc/1120723.html
3. http://www.cocoachina.com/ios/20170124/18617.html
4. http://charsdavy.github.io/2016/07/29/animation-caanimation/

2017年1月8日 星期日

iOS筆記:React Native環境建置

React Native 是 Facebook 推出的一個用 JavaScript 語言就能同時編寫 iOS,Android,以及後台的一項技術

1. 安裝Node 和 Watchman

    $ brew install node
    $ brew install watchman
Watchman 是來自 Facebook 的檔案監控工具。 React Native 利用 Watchman 來偵測程式碼的變化,以便重新建構。

2. 安裝React Native CLI

    $ npm install -g react-native-cli

enter image description here

3. iOS環境

有安裝Mac的Xcode即可.

4. Android環境

安裝Android studio. 另外還需要Java SE Development Kit 8.

enter image description here

5. Install Android SDK

開啟安裝完的Android studio, 選擇右下角的”Configure”, 選擇 “SDK Manager”, 會出現下面的畫面:

enter image description here

打勾右下角的 Show Package Details, 勾 Android 6.0 (Marshmallow) 下的這些:
- Android SDK Platform
- Google APIs
- Intel x86 Atom System Image
- Intel x86 Atom_64 System Image
- Google APIs Intel x86 Atom_64 System Image

切換到分頁 SDK Tools, 繼續安裝需要的工具.
- Android SDK Build Tools
- Android SDK Tool
- Google Play Services

6. Set up the ANDROID_HOME environment variable

如果你使用的是bash,那就在~/.bashrc文件中加入以下内容,如果是用zsh,那就是~/.zshrc.
    export ANDROID_HOME=~/Library/Android/sdk
    export PATH=${PATH}:${ANDROID_HOME}/tools
    export PATH=${PATH}:${ANDROID_HOME}/platform-tools

7.新增專案

虛擬機的部分我是使用“Genymotion”的. 要注意的是需要設定Android SDK的位址(路徑可以在 SDK Manager 上找到).

enter image description here

新增專案

    $ react-native init HelloWorld
移動到專案中執行”npm start“並先將Android虛擬機開啟.
然後就可以執行run-ios跟run-android.

enter image description here


enter image description here

Issue

  1. 會發生這問題的原因是忘記把Android的虛擬機開啟就執行run-android導致.
    Key world: :app:installDebug

enter image description here

Reference:

  1. https://facebook.github.io/react-native/
  2. https://github.com/facebook/react-native
  3. http://reactnative.cn/
  4. https://github.com/jondot/awesome-react-native
  5. http://makeitopen.com/



2017年1月4日 星期三

iOS筆記:Swift3 GCD

Grand Central Dispatch (GCD)

在iOS當中,蘋果提供兩個方法來實作多工任務:包含Grand Central Dispatch (GCD)以及NSOperationQueue的frameworks,它們都可以幫助開發者達到多個任務分配給多個執行緒或不同queues進行同步運行的需求.

主佇列都是用來處理UI接收到的指令,所以跑在主執行緒的任務是最優先執行的
有時候都會在completion handler block執行以下的方式來更新UI, 主要的原因是因為原本的狀況並不是在main queue刷新UI介面, 所以可能你的圖片已經下載好了 但礙於不是在main queue所以會沒辦法及時被更新而產生很多error log.

    DispatchQueue.main.async {
        self.imageView.image = UIImage(data: data)
    }

GCD在swift上一直都是基於C建立的, 之前也有聽人說過如果把swift上跟dispatch相關的程式碼貼到linux上可以直接運作. 但這件事情在Swift 3上應該是不會再發生了. 因為這方面進行了大改版. 詳細的部分請參考Reference.

Dispatch framework

  1. DispatchQueue
    取代原本Dispatch async的工能, 建立一個queue最基本的語法:

        let queue = DispatchQueue(label: "dispatchQueue")

    queue一旦被建立後,我們就可以透過程式碼使用它,同步則使用sync函式,若非同步則呼叫async函式,當我們開始時,先提供一段code當做一個block(closure).

            queue.async {
            for _ in 1...10 {
                print("111111111")
            }
        }
  2. DispatchQoS (Quality of Service)
    可以去決定執行緒的權重(優先順序), 右邊為Swift 3現在的語法, 左邊則是對應到之前的權限是多大. 根據想要的優先順序,提供一個適當的QoS值在佇列初始化作業,如果沒有特別定義,佇列則預設為 default priority.

    enter image description here

    測試的話可以先定義兩條queue然後再用forloop看執行結果就可以明顯看出優先權高跟低的差異.

    let queue1 = DispatchQueue(label: "com.appcoda.queue1", qos: DispatchQoS.userInitiated)
let queue2 = DispatchQueue(label: "com.appcoda.queue2", qos: DispatchQoS.utility)
  1. DispatchWorkItem
    DispatchWorkItem是一個代碼塊(可以想成是把closure封裝成一個item),可以在任何的佇列上面被調用,因此,裡面的程式碼可以在背景執行,或是在主執行緒運行.

        //workItem的目的是將value變量的值增加5
        func useWorkItem() {
            var value = 10
    
            let workItem = DispatchWorkItem {
                value += 5
            }
        }
    
        //調用方式
        let queue = DispatchQueue.global()
        queue.async {
            workItem.perform()
        }

另外也有比較快的方式可以調用work item,DispatchQueue類別為此目的提供了一種方便的方法:

    queue.async(execute: workItem)
  1. DispatchTime 延遲時間
    now()方法會回傳目前時間,另外再把想要延遲的時間添加進來.
    func dispatchTime() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) { 
            //兩秒後才會被執行
            print("兩秒了")
        }
    }

Reference:
1. http://www.appcoda.com.tw/grand-central-dispatch/