UIActivityViewControllerにActivityを追加する方法

UIActivityViewControllerで「共有」みたいなメニューを追加できるようになると、そこに自分のアプリケーション独自の機能を入れたくなりました。
追加機能は、UIActivityViewControllerから見ると2種類に分けられて、「処理を実行する」と「ユーザーから追加の入力を受けて処理を実行する」。
まぁ、選択後に別のビューを表示する必要があるかどうかの違いです。

Activity

Activityは、実際には、UIActivityというクラスを継承したものを使い必要があります。以下のような形で実装する感じ。
プロパティ等の詳細は、Appleドキュメントを参照してください。

class LabelConfigActivity: UIActivity {
    override var activityTitle: String? {
        get {
            return "Config Label"
        }
    }
    override var activityType: UIActivity.ActivityType {
        get {
            return .init("ConfigLabel")
        }
    }
    override var activityImage: UIImage? {
        get {
            return UIImage.init(systemName: "slider.horizontal.3")
        }
        
        }
    override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
        // always true
        return true
    }
    override func prepare(withActivityItems activityItems: [Any]) {
        return
    }
    override func perform() {
      // process something
    }
    override var activityViewController: UIViewController? {
       return someViewController
    }
}

Activity実装のポイント

実際には、performとactivityViewのどちらかだけの実装を選択します。
具体的には、選択されたことをきっかけに処理を実行するだけであれば、performを実装すればよくて、何かビューを表示してユーザーとさらにやり取りする必要があれば、activityViewControllerを実装することとなります。

Activityが表示されるためには

UIActivityViewControllerをインスタンス化するときに、引数として渡すことのできる applicationActivitiesとして設定することで表示されるようになります。
以下、サンプルコード

let selectPhotoActivity = PhotoSelectActivity.init(mainViewController: self)
let labelConfigActivity = LabelConfigActivity.init(mainViewController: self)

let activityVC = UIActivityViewController(activityItems: [self], applicationActivities: [selectPhotoActivity, labelConfigActivity])
activityVC.title = "ExifClip2"
activityVC.popoverPresentationController?.sourceView = self.view
// (10, 5) is padding from upper-left corner
activityVC.popoverPresentationController?.sourceRect = CGRect.init(x: 50, y: self.view.bounds.height, width: 15, height: self.imageView.frame.origin.y + 5)
activityVC.excludedActivityTypes = [
    .assignToContact,
]
present(activityVC, animated: true, completion: nil)

このように実装していくと、iOSから提供されるサービス(この場合は、共有メニューとそこに表示される標準機能)と自分で開発した機能が 一緒に表示されるようになるので、アプリケーションのiOSとの親和性が高く見えるようになります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です