しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

PHPickerViewControllerで画像を取得する

PHPickerViewControllerというiOS14から登場したクラスで画像を取得してみました。
このクラスはUIImagePickerControllerと違って複数画像を選択することなども可能です。

まずは画面に画像選択用のボタンを設置します。

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let button = UIButton()
        button.setTitle("画像選択", for: .normal)
        button.setTitleColor(.black, for: .normal)
        button.addTarget(self, action:#selector(self.tapButton), for: .touchUpInside)
        button.sizeToFit()
        button.center = view.center
        view.addSubview(button)
    }
    
    @objc func tapButton() {
    }
}

画面の真ん中にボタンを設置できました。

f:id:llcc:20210514115016p:plain

次はボタンを押すとPHPickerViewControllerが立ち上がるようにします。
画像選択可能数などの設定はPHPickerConfigurationを使って行っています。

import PhotosUI

class ViewController: UIViewController {
    override func viewDidLoad() {
        // 省略
    }
    
    @objc func tapButton() {
        var config = PHPickerConfiguration()
        config.filter = .images
        config.selectionLimit = 0
        let pickerView = PHPickerViewController(configuration: config)
        present(pickerView, animated: true, completion: nil)
    }
}

無事にPickerを表示できました。

f:id:llcc:20210514115227p:plain

最後にUIImageの取得処理を実装します。
画像の取得はPHPickerViewControllerDelegateで行います。

class ViewController: UIViewController {
    @objc func tapButton() {
        let pickerView = PHPickerViewController(configuration: config)
        pickerView.delegate = self // 追加
        present(pickerView, animated: true, completion: nil)
    }
}

extension ViewController: PHPickerViewControllerDelegate {
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true, completion: nil)
        results.forEach {
            $0.itemProvider.loadObject(ofClass: UIImage.self) { image, error in
                print(image)
            }
        }
    }
}

ログを見ると正しく画像が選択できている事が分かります。

f:id:llcc:20210514115407p:plain

注意点ですがloadObjectは非同期の為、読み込み完了順に呼ばれます。
そのため画像選択の順番は保持されません。
もし順番を保持したい場合、保持するような仕組みを実装する必要があります。