0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Swift】フォトライブラリでの写真の複数選択を実現する(高画質化)

Last updated at Posted at 2022-09-25

はじめに

写真アプリで「フォトライブラリから写真を複数同時に取り込む機能」を実装しようとした際に、
こちらの記事を参考にしたのですが、ハマったことがあったので、記事にしてみようと思いました。

ハマった点は以下の3点です。

  • 単純に複数画像を選択するだけなら「imageManager.requestImage」を使えばいいのですが、この場合選択した画像がかなり低画質になってしまい使い物にならなかった。
  • Storyboadを使わずにコードでUIを設定していたので他の機能を追加しづらかった。
  • 長押しドラッグ(?)で複数選択ができない。(未実装)

本題

基本的なことは元ネタの記事を見てください。
また、元ネタの記事同様コードが長く重すぎるのでコードはGitHubに公開しておきました。
https://github.com/YoshihisaTanaka-prog/PhotosMultiSelect

変更点

高画質化

まず、以下の部分を以下に書き換えました。

LibraryPhotoViewController.swift(before) (220-230行目付近)
    imageManager.requestImage(for: asset, targetSize: thumbnailSize, contentMode: .aspectFill, options: nil, resultHandler: { image, _ in
        if image == nil {
            print("managerError")
        } else {
            self.items.append(image! as UIImage)
        }
    })
LibraryPhotoViewController.swift(after) (220-230行目付近)
    imageManager.requestImageDataAndOrientation(for: asset, options: nil, resultHandler: { data, _, _, _ in
        if data == nil {
            print("managerError")
        } else {
            if let image = UIImage(data: data!){
                self.items.append(image)
                if(self.items.count == indexPaths.count){
                    self.mainView.items = self.items
                    self.mainView.photoCollectionView.reloadData()
                    self.dismiss(animated: true, completion: nil)
                }
            }
        }
    })

しかし、このまま状態では非同期処理を行うためメインの画面に全く反映されなかったので「DispatchQueue.main.async」を追加しました。

LibraryPhotoViewController.swift(add DispatchQueue) (220-230行目付近)
    imageManager.requestImageDataAndOrientation(for: asset, options: nil, resultHandler: { data, _, _, _ in
        if data == nil {
            print("managerError")
        } else {
            if let image = UIImage(data: data!){
                DispatchQueue.main.async {
                self.items.append(image)
                    if(self.items.count == indexPaths.count){
                        self.mainView.items = self.items
                        self.mainView.photoCollectionView.reloadData()
                        self.dismiss(animated: true, completion: nil)
                    }
                }
            }
        }
    })

(追記2022-09/29)
このままでは画像の順番がバラバラになってしまうのでもう少し修正しておきました。
詳しくはGitHubのコードを見てください。一応大まかに何をしたのかを書いておきます。

  1. 同期処理部分にUIImage配列の要素を追加するようにし、非同期部分にindexを送りその部分を上書きするようにしました。
  2. 全てを上書きしたかどうかを確認するためのBoolean配列を作り、上書きが全て完了した時点で最初の画面に戻るようにしました。

(ここまで追記です)

これでうまく動くようになりました。

Storyboadの対応

Storyboadへの対応は特筆すべき点はありません。

長押しドラッグ選択の対応

未実装です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?