Blog スタッフブログ

iOS Swift システム開発

[iOS]iOS16からの新機能UIPasteControlを使ってみた

Swift

こんにちは、株式会社MIXシステム開発担当のBloomです。

早速本題のiOS16から追加された新機能であるUIPasteControlを利用する手順について、

お仕事の中で得た知見を共有させていただきたいと思います。

UIPasteControlとは

UIPasteControl – Apple Developer Documentation

iOS16から追加されたいわゆる「貼り付け」機能をサポートするUIパーツです。

それだけといえばそれだけですが、iOS16ではクリップボードの中身をこれまでの UIPasteboard.general によるペースト機能を利用した場合確認アラートが表示されるようになっています。

ここでUIPasteControlを利用することで確認アラートを表示せず、ユーザ操作による貼り付けが可能となります。

それでは実際に実装コード例を見てみましょう。

    @IBOutlet weak var pasteControl: UIPasteControl!
    override func viewDidLoad() {
        super.viewDidLoad()
        pasteControl.target = self
        pasteConfiguration = UIPasteConfiguration(acceptableTypeIdentifiers: [UTType.text.identifier,
                                                                              UTType.image.identifier])
    }
    
    override func paste(itemProviders: [NSItemProvider]) {
        for provider in itemProviders {
            if provider.hasItemConformingToTypeIdentifier(UTType.text.identifier) {
                let progress = provider.loadObject(ofClass: String.self) { str, error in
                    if error == nil, let str = str {
                        DispatchQueue.main.async { // 更新操作はUIスレッドで行う
                            self.textView.text = str
                        }
                    }
                }
            } else if provider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
                // https://stackoverflow.com/a/74759438
                // 場合によっては明示的に型を指定しなければloadObject(obClass:)でエラーが発生する
                let type: NSItemProviderReading.Type = UIImage.self
                _ = provider.loadObject(ofClass: type) { img, error in
                    if error == nil, let img = img as? UIImage {
                        DispatchQueue.main.async {
                            self.imageView.image = img
                        }
                    }
                }
            }
        }
    }

このコード例ではStoryboard上に配置したUIPasteControlのペースト先を自分のViewControllerとした上で、

paste(itemProviders: [NSItemProvider])をオーバーライドすることでペーストする文字と画像を受け取らせる機能を設置しています。

単にTextViewへ直接貼り付けたいだけであれば pasteControl.target = textView のような形式で直接指定しても問題ありません。

これで簡単に貼り付け処理を実装できました。良かったですね。

参考文献

UIPasteControl – Apple Developer Documentation

How to Use UIPasteControl in iOS 16 – blog.kylelanchman.com

UIImage must conform to _ObjectiveCBridgeable in PHPickerViewControllerDelegate callback – Stack Overflow