[CS193P] 第十五堂課摘要及心得筆記

在先前的課程中,我們所學習到的大多都是軟體上API的呼叫,並沒有使用到太多硬體上的裝置設備。而在這一次的內容中,我們就會看到如何使用Cocoa Touch的API來操作iPhone的硬體,使用像是加速度感應器、羅盤和地理定位系統等裝置來創造出更多有趣的應用,還請多多指教!
評論
評論

在先前的課程中,我們所學習到的大多都是軟體上 API 的呼叫,並沒有使用到太多硬體上的裝置設備。而在這一次的內容中,我們就會看到如何使用 Cocoa Touch 的 API 來操作 iPhone 的硬體,使用像是加速度感應器、羅盤和地理定位系統等裝置來創造出更多有趣的應用,還請多多指教!

Image Picker

在前幾次的課程內容中,我們在學習 Modal View 的呈現時,曾經有看過如何使用 UIImagePickerController 來讓使用者選取影像。而當我們需要使用照相機、攝影機的硬體功能時,也同樣是透過 Image Picker 來達成。

在 iPhone 平台上,我們主要有以下幾種影像來源:

  • UIImagePickerControllerSourceTypePhotoLibrary -- 照片資料庫(包含同步而來的照片)
  • UIImagePickerControllerSourceTypeCamera -- iPhone 上的照相鏡頭
  • UIImagePickerControllerSourceTypeSavedPhotosAlbum -- 相片膠卷(也就是拍過的照片)

而 Image Picker 提供了 -(BOOL) isSourceTypeAvailable 這個方法讓我們檢查所需要的影像來源是否可以使用(像是 iPod 上就不能使用照相機)。在確定影像來源之後,我們可以設定 sourceType 屬性,來決定使用者可以在這個 Image Picker 中使用哪種影像來源。

此外,UIImagePicker 也有提供 allowsImageEditing 屬性,當這個屬性被設定成 YES 之後,我們就可以讓使用者移動、裁剪照片後再回傳,如下圖所示:

透過 delegate 的設定,在使用者挑選完照片或是拍完照片之後變會呼叫 delegate 方法,或者是使用者取消選取之後,也會呼叫 delegate 方法。這些方法都定義在 UIImagePickerControllerDelegate 中,分別是:

- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo; // 選取完畢 - (void)imagePickerControllerDidCancel: (UIImagePickerController*)picker; // 取消選取

透過這些方法的呼叫,我們可以取得使用者所挑選的照片,包含裁剪過後的照片和原始檔。要注意的是,在 UIImagePicker 呼叫了這些方法之後,我們必須自己在程式中將 Picker 從畫面上移除,並且 release。投影片的第 18、19 頁有簡單的範例程式碼可以參考。

而我們前面有提過,UIImagePicker 有提供讓使用者自行裁剪照片的功能,在我們開啟這項功能之後,delegate 方法所回傳的 UIImage 就會是裁剪過後的照片。而如果我們希望同時也可以取得原始檔的話,則是透過 editingInfo 中的 UIImagePickerControllerOriginalImage 來取回。

最後,當我們完成照片的操作之後,若有需要將照片存回使用者的相簿中則可以透過呼叫 UIImageWriteToSavedPhotosAlbum 這個由 UIKit 所提供的函式,而這個函式也可以在存檔完成後另外呼叫一個 callback 方法作為通知。

整體來講,大概有幾個重點:

  1. 確認影像來源是否可以使用
  2. delegate 方法要清理畫面和記憶體
  3. 影像佔記憶體很多空間,盡量都寫到檔案系統中
  4. 可以在 iPhone Simulator 中模擬大多數的操作

Core Location

Core Location 是 iPhone 上用來存取地理定位系統的 Framework,主要透過 CLLocationManager 來取得 CLLocation,後者即包含了各種我們所需要的座標資料。

需要注意的是,不同於其他的 delegate 設計,CLLocationManager 只會在使用者更新座標的時候呼叫 delegate 方法,而不是在固定的時間間隔呼叫。

其他 Core Location 的細節說明,還請參考筆者的 第十二堂課摘要及心得筆記 ,其中對於 CCLocationManager 等類別的使用均有說明。

加速度感應器

iPhone 除了優異的多點觸控螢幕之外,也具備了加速度感應器讓開發者可以發揮想像力,設計許多創新的互動方法。如下圖所顯示的,當我們將 iPhone 或是 iPod 側向一旁的時候,其具備的加速度感應器也會偵測到改變。

而加速度感應器最基本的應用莫過於旋轉畫面的顯示了,這樣的功能在 Safari 和 iPhoto 等應用程式中都很常見。我們可以透過 UIDevice 類別來取得目前裝置的方向:

  • beginGeneratingDeviceOrientationNotifications -- 開始傳遞方向訊息
  • UIDeviceOrientationDidChangeNotification -- 方向改變中
  • endGeneratingDeviceOrientationNotifications -- 停止傳遞方向訊息

而 UIDevice 中也有 orientation 屬性可以直接取得目前的方向。

然而,硬體的方向跟目前介面上的方向有可能會是不一致的,我們可以從 UIApplication 的 statusBarOrientation 屬性知道目前介面的方向,並且透過 UIViewController 的以下方法來設定介面選轉的功能:

- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation

在大多數的情況下,我們只要設定好以上 UIViewController 的方法,就可以讓介面進行正確的旋轉動作了。

而在 iPhone OS 3.0 之後,Cocoa Touch 也新增了一種 UIEvent 叫做 Shake。就如同多點觸控一般,我們可以透過重載 UIResponser 的 – motionBegan:withEvent: 等一系列的方法來取得 shake 的動作,並且進行相對應的處理。

一般而言,在 iPhone 上的 shake 動作通常代表著「還原」的功能,或者是「隨機播放」這樣的意思。所以如果在設計的過程中需要賦予 shake 動作不同的意義,要記得一定要對使用者詳加提示,避免混淆。

針對一般的應用程式,或許以上的功能已經相當的夠用,但針對遊戲等來講,我們會希望能夠有詳細的加速度數字,以便提供細微的操作。在 iPhone 平台上,加速度感應器分成六軸,如下圖:

而加速度感應器的使用上,與 Core Location 可以說是相當的類似,UIAccelerometer 會以每秒 10~100 的頻率傳遞 UIAcceleration 給 delegate,程式碼如下:

- (void)enableAccelerometerEvents {     UIAccelerometer* theAccel = [UIAccelerometer sharedAccelerometer];     theAccel.updateInterval = 1/50;     theAccel.delegate = self;

比較特別的是,不同於 CLLocationManager,我們不需要建立個別的 UIAccelerometer,只需要呼叫 + sharedAccelerometer 來取得共用的實體物件即可。此外,我們也不需要呼叫某個方法來「開始」,只需要將 delegate 設定好就會開始接收資訊了。至於如果要停止更新的話,則是將 delegate 設定為 nil 就可以了。

在投影片第 85 到 99 頁中,有對實務操作上的一些範例,像是如何透過簡單的數學運算來過濾加速器的資料等等,有興趣的讀者還務必參考。

結論

在這一堂課程中,我們看到許多 iPhone 硬體資源的使用範例以及學習了相關的操作方法。在下一次的課程中

參考資源



精選熱門好工作

SRE 專家 / Sr. SRE

奔騰網路科技有限公司
臺北市.台灣

獎勵 NT$15,000

公關活動企劃專員

八方采整合行銷有限公司
新北市.台灣

獎勵 NT$15,000

資深人力資源專員

VeryBuy非常勸敗
臺北市.台灣

獎勵 NT$15,000