基於Swift的iOS應用程序開發:使用UIImagePickerController從相冊選擇圖片

一、設置系統權限

這一點非常重要,找到工程內的info.plist文件,在其中添加以下項:
Privacy - Photo Library Usage Description
爲你添加的項設置Type爲String,然後在Value一列中輸入一句話,可以任意輸入,這句話旨在提醒用戶我們需要獲得使用攝像頭的權限:

二、實現/繼承代理

調取系統相冊需要用到以下兩個系統代理:
UIImagePickerControllerDelegate
UINavigationControllerDelegate
所以我們的ViewController需要實現這兩個代理:
import UIKit

class DemoTakePhotoViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
//...
}

三、編寫方法,調取系統相冊

調取攝像頭其實就是呼出一個系統已定義的ViewController:
UIImagePickerController
具體使用該ViewController的方式如下:
let photoPickerViewController:UIImagePickerController = UIImagePickerController()
photoPickerViewController.sourceType = UIImagePickerControllerSourceType.photoLibrary
photoPickerViewController.delegate = self
self.present(photoPickerViewController, animated: true, completion: nil)

注意上面代碼中,在第二行等號的右邊所出現的以下代碼:
UIImagePickerControllerSourceType.photoLibrary
就是這句代碼,指定了UIImagePickerController要打開的是系統相冊,我們可以查看一下UIImagePickerControllerSourceType類的源代碼,發現它本身是一個枚舉:
public enum UIImagePickerControllerSourceType : Int {
 
    case photoLibrary

    case camera

    case savedPhotosAlbum
}
這個枚舉非常簡單易懂:
photoLibrary:系統圖庫
camera:系統攝像頭
savedPhotosAlbum:相冊
也就是說我們可以通過設置photoPickerViewController的sourceType爲上述三項中的一項,來決定調用哪個系統功能

稍微進一步查看一下源代碼,我們發現還有其它非常多的枚舉量:
public enum UIImagePickerControllerSourceType : Int {

    
    case photoLibrary

    case camera

    case savedPhotosAlbum
}

public enum UIImagePickerControllerQualityType : Int {

    
    case typeHigh // highest quality

    case typeMedium // medium quality, suitable for transmission via Wi-Fi 

    case typeLow // lowest quality, suitable for tranmission via cellular network

    @available(iOS 4.0, *)
    case type640x480 // VGA quality

    @available(iOS 5.0, *)
    case typeIFrame1280x720

    @available(iOS 5.0, *)
    case typeIFrame960x540
}

public enum UIImagePickerControllerCameraCaptureMode : Int {

    
    case photo

    case video
}

public enum UIImagePickerControllerCameraDevice : Int {

    
    case rear

    case front
}

public enum UIImagePickerControllerCameraFlashMode : Int {

    
    case off

    case auto

    case on
}
看懂這些枚舉量的用途不需要太好的英文水平,除了在本例中用到的UIImagePickerControllerSourceType外,我在這裏將其它枚舉量簡單做個說明:

UIImagePickerControllerQualityType:成像質量

UIImagePickerControllerCameraCaptureMode:拍照或者錄像

UIImagePickerControllerCameraDevice:選擇前置攝像頭或是後置攝像頭

UIImagePickerControllerCameraFlashMode:閃光燈模式


不再展開了,繼續回來。我將調用攝像頭拍照的代碼封裝成了一個方法,便於綁定到觸發事件上:
/**
 *  當用戶點擊界面上的相冊按鈕時,會打開系統相冊,從而讓用戶選擇照片
 */
@IBAction func pickPhotoFromAlbum(_ sender: Any) {
    /*
     *  用來打開系統相冊的view controller
     */
    let photoPickerViewController:UIImagePickerController = UIImagePickerController()
    photoPickerViewController.sourceType = UIImagePickerControllerSourceType.photoLibrary
    photoPickerViewController.delegate = self
    self.present(photoPickerViewController, animated: true, completion: nil)

}

四、編寫方法,獲取從相冊選擇的圖片

要獲取從相冊所拍選擇的圖片,我們主要需要重載以下方法:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
//...
}
注意這個方法入參列表中的第二個參數“didFinishPickingMediaWithInfo info:[String : Any]”,選擇的結果就會被保存在這個參數裏面,我們可以通過以下方法來獲取:
guard var selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
    fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
這樣一來,從相冊選擇的照片就成爲了一個UIImage對象。
下面貼出完整的方法:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    guard var selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
        fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
    }

    picker.dismiss(animated: true, completion: nil)
}
拿到了UIImage對象後,我們就可以做自己需要的操作了,比如將圖片顯示在界面上,或是上傳到服務器

五、編寫方法,取消選擇

以下方法爲我們提供了退出相冊的途徑:
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
    picker.dismiss(animated: true, completion: nil)
}

小結

調取相冊的各項功能都用到了Swift提供的代理(delegate)機制,它的最大的好處在於,在上述各步驟中,我們只有在調取相冊的時候需要手動觸發,其它方法全部都由代理自動調用,我們只要實現這些方法就可以了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章