CS193P第十五堂课摘要及心得笔记

2020-06-06 作者: 围观:103 62 评论

在先前的课程中,我们所学习到的大多都是软体上 API 的呼叫,并没有使用到太多硬体上的装置设备。而在这一次的内容中,我们就会看到如何使用 Cocoa Touch 的 API 来操作 iPhone 的硬体,使用像是加速度感应器、罗盘和地理定位系统等装置来创造出更多有趣的应用,还请多多指教!

Image Picker

在前几次的课程内容中,我们在学习 Modal View 的呈现时,曾经有看过如何使用 UIImagePickerController 来让使用者选取影像。而当我们需要使用照相机、摄影机的硬体功能时,也同样是透过 Image Picker 来达成。

在 iPhone 平台上,我们主要有以下几种影像来源:

而 Image Picker 提供了 - isSourceTypeAvailable 这个方法让我们检查所需要的影像来源是否可以使用。在确定影像来源之后,我们可以设定 sourceType 属性,来决定使用者可以在这个 Image Picker 中使用哪种影像来源。

此外,UIImagePicker 也有提供 allowsImageEditing 属性,当这个属性被设定成 YES 之后,我们就可以让使用者移动、裁剪照片后再回传,如下图所示:

CS193P第十五堂课摘要及心得笔记

透过 delegate 的设定,在使用者挑选完照片或是拍完照片之后变会呼叫 delegate 方法,或者是使用者取消选取之后,也会呼叫 delegate 方法。这些方法都定义在 UIImagePickerControllerDelegate 中,分别是:

- imagePickerController:picker didFinishPickingImage:image editingInfo:editingInfo; // 选取完毕 - imagePickerControllerDidCancel: picker; // 取消选取

透过这些方法的呼叫,我们可以取得使用者所挑选的照片,包含裁剪过后的照片和原始档。要注意的是,在 UIImagePicker 呼叫了这些方法之后,我们必须自己在程式中将 Picker 从画面上移除,并且 release。投影片的第 18、19 页有简单的範例程式码可以参考。

而我们前面有提过,UIImagePicker 有提供让使用者自行裁剪照片的功能,在我们开启这项功能之后,delegate 方法所回传的 UIImage 就会是裁剪过后的照片。而如果我们希望同时也可以取得原始档的话,则是透过 editingInfo 中的 UIImagePickerControllerOriginalImage 来取回。

最后,当我们完成照片的操作之后,若有需要将照片存回使用者的相簿中则可以透过呼叫 UIImageWriteToSaved

整体来讲,大概有几个重点:

  1. 确认影像来源是否可以使用
  2. delegate 方法要清理画面和记忆体
  3. 影像佔记忆体很多空间,尽量都写到档案系统中
  4. 可以在 iPhone Simulator 中模拟大多数的操作
Core Location

Core Location 是 iPhone 上用来存取地理定位系统的 Framework,主要透过 CLLocationManager 来取得 CLLocation,后者即包含了各种我们所需要的座标资料。

需要注意的是,不同于其他的 delegate 设计,CLLocationManager 只会在使用者更新座标的时候呼叫 delegate 方法,而不是在固定的时间间隔呼叫。

其他 Core Location 的细节说明,还请参考笔者的 第十二堂课摘要及心得笔记 ,其中对于 CCLocationManager 等类别的使用均有说明。

加速度感应器

iPhone 除了优异的多点触控萤幕之外,也具备了加速度感应器让开发者可以发挥想像力,设计许多创新的互动方法。如下图所显示的,当我们将 iPhone 或是 iPod 侧向一旁的时候,其具备的加速度感应器也会侦测到改变。

CS193P第十五堂课摘要及心得笔记

而加速度感应器最基本的应用莫过于旋转画面的显示了,这样的功能在 Safari 和 i

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

然而,硬体的方向跟目前介面上的方向有可能会是不一致的,我们可以从 UIApplication 的 statusBarOrientation 属性知道目前介面的方向,并且透过 UIViewController 的以下方法来设定介面选转的功能:

- shouldAutorotateToInterfaceOrientation: interfaceOrientation

在大多数的情况下,我们只要设定好以上 UIViewController 的方法,就可以让介面进行正确的旋转动作了。

而在 iPhone OS 3.0 之后,Cocoa Touch 也新增了一种 UIEvent 叫做 Shake。就如同多点触控一般,我们可以透过重载 UIResponser 的 – motionBegan:withEvent: 等一系列的方法来取得 shake 的动作,并且进行相对应的处理。

一般而言,在 iPhone 上的 shake 动作通常代表着「还原」的功能,或者是「随机播放」这样的意思。所以如果在设计的过程中需要赋予 shake 动作不同的意义,要记得一定要对使用者详加提示,避免混淆。

CS193P第十五堂课摘要及心得笔记
针对一般的应用程式,或许以上的功能已经相当的够用,但针对游戏等来讲,我们会希望能够有详细的加速度数字,以便提供细微的操作。在 iPhone 平台上,加速度感应器分成六轴,如下图:

而加速度感应器的使用上,与 Core Location 可以说是相当的类似,UIAccelerometer 会以每秒 10~100 的频率传递 UIAcceleration 给 delegate,程式码如下:

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

比较特别的是,不同于 CLLocationManager,我们不需要建立个别的 UIAccelerometer,只需要呼叫 + sharedAccelerometer 来取得共用的实体物件即可。此外,我们也不需要呼叫某个方法来「开始」,只需要将 delegate 设定好就会开始接收资讯了。至于如果要停止更新的话,则是将 delegate 设定为 nil 就可以了。

在投影片第 85 到 99 页中,有对实务操作上的一些範例,像是如何透过简单的数学运算来过滤加速器的资料等等,有兴趣的读者还务必参考。

结论

在这一堂课程中,我们看到许多 iPhone 硬体资源的使用範例以及学习了相关的操作方法。在下一次的课程中

参考资源
相关浏览推荐