Live Photos(ライブフォト)を表示するクラス PHLivePhotoView を試す


iOS 9.1 で追加された PHLivePhoto, PHLivePhotoView を使ってみます。

各種フレームワークのインポート

まずは Photos, PhotosUI, MobileCoreService を import します。

import Photos
import PhotosUI
import MobileCoreServices

Photos は PHLivePhoto、PhotosUI は PHLivePhotoView を使うために必要で、MobileCoreServices はピッカーにメディアタイプを指定するのに必要になります。(なので、UIImagePickerController を使わないなら必要ない)

PHLivePhotoView のセットアップ

プロパティを定義して、

@IBOutlet weak var livePhotoView: PHLivePhotoView!

storyboard で適当な UIView オブジェクトを置いて、クラスを PHLivePhotoView にして、アウトレットを接続します。

PHLivePhotoViewDelegate への準拠を宣言しておきます。

class ViewController: UIViewController, PHLivePhotoViewDelegate

viewDidLoad あたりで PHLivePhotoView の各種プロパティを必要に応じてセットします。

livePhotoView.contentMode = UIViewContentMode.ScaleAspectFit
livePhotoView.delegate = self

ライブフォト選択

ここでは UIImagePickerController を使うことにします。

UIImagePickerControllerDelegate, UINavigationControllerDelegate プロトコルへの準拠を宣言しておきます。

class ViewController: UIViewController, PHLivePhotoViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate

こんな感じでピッカーを表示するアクションメソッドを実装します。

@IBAction func pickerBtnTapped(sender: UIButton) {

    let picker = UIImagePickerController()
    picker.sourceType = .PhotoLibrary
    picker.delegate = self
    picker.mediaTypes = [kUTTypeImage as String, kUTTypeLivePhoto as String]

    self.presentViewController(picker, animated: true, completion: nil)
}

mediaTypeskUTTypeLivePhoto を入れるところが肝ではありますが、kUTTypeImage も入れないといけない(入れないと実行時に怒られる)ので、結局ライブフォトではない画像もリストに出てきてしまいます。。

選択されたときに呼ばれるデリゲートメソッドを実装します。

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

    self.dismissViewControllerAnimated(true, completion: nil)

    let livePhoto = info[UIImagePickerControllerLivePhoto] as? PHLivePhoto

    if let livePhoto = livePhoto {

        // ライブフォトを表示・再生する(後述)
    }
}

info 辞書から UIImagePickerControllerLivePhoto キーで PHLivePhoto オブジェクトが取り出せる点がここでのポイントになります。

参考記事:

再生する

先ほど取得した PHLivePhoto オブジェクトを、PHLivePhotoView の livePhoto にセットし、startPlaybackWithStyle: メソッドで再生開始するだけ。

livePhotoView.livePhoto = livePhoto
livePhotoView.startPlaybackWithStyle(.Full)

ちなみに startPlayback〜 の引数には

case Undefined
case Full
case Hint

のいずれかが指定できます。

リピート再生

繰り返し再生したければ、PHLivePhotoDelegate の livePhotoView:didEndPlaybackWithStyle: を実装しておき、そこで再生を再開するようにします。

func livePhotoView(livePhotoView: PHLivePhotoView, didEndPlaybackWithStyle playbackStyle: PHLivePhotoViewPlaybackStyle) {
    print(__FUNCTION__+"\n")

    livePhotoView.startPlaybackWithStyle(.Full)
}

出来上がり

その他

音を消す

PHLivePhotoView の muted プロパティに true をセットすれば良さそうです(試していません)

ジェスチャーで再生操作

PHLivePhotoView の playbackGestureRecognizer プロパティを print してみたら、

<UILongPressGestureRecognizer: 0x15ee554f0; state = Possible; view = <ISPlayerView 0x15ee46340>; targets= <(
    "(action=_handlePress:, target=<ISForcePressPlaybackInput 0x15ee54ec0>)",
    "(action=_handleGesture:, target=<ISPlayerView 0x15ee46340>)"

こうなったので、最初からジェスチャーで再生をコントロールできるようになっているようです。(自動繰り返し処理を止めて、強タップを試してみたら再生開始しました)

サンプルコード

同様のサンプルを iOS-9-Sampler に追加してあります。