Categories: iOS

[iOS] いい感じに画像のプレビューを出せるImageViewerをサクッと使う

チャットを作っているのですが、画像をタップしたら、画像のプレビュー出したいときあるじゃないですか。

それをいい感じにさっとだせるKrisiacik/ImageViewerがあったので紹介。

こんな感じのものが表示できます。

意外に日本語記事がない。

インストール方法

インストールはサクッといれましょう。
CocoaPods

pod 'ImageViewer'

Carthage

github "MailOnline/ImageViewer"

how to show

READMEが若干やさしくなくて、どうやって表示すればいいのか?という疑問に対してExample見てねという投げっぷり。

ギャラリーとして表示したり、動画も再生できたりするのですが、とりあえずは一枚の画像を表示できればいいので、その表示の仕方を載せときます。

ちなみに、今回は下記を参考にURLからとってきた画像を表示しています。

Hello, I've been having trouble figuring out how to setup the asynchronous loading of images in galleryviewcontroller. Could you provide a snippet that will give me a hint on how to do this?
Asynchronous loading images in galleryviewcontroller · Issue #59 · Krisiacik/... - GitHub

Nukeつかってますが、SDWebImageでも、PINRemoteImageでもそこはいい感じに置き換えられます。

最初にGallery周りの設定をするGalleryDelegate.swiftを作ります。
今回は別ファイルに切り出してますが、めんどくさかったらUITableViewDelegateみたいに、UIViewControllerni直に継承とかでもいいです。

import ImageViewer
import Foundation
import Nuke

class GalleryDelegate: GalleryItemsDataSource {
    private let items: [GalleryItem]
    // 一応ギャラリーとしても使えるように複数のURL読み込みに対応してます。
    init(imageUrls: [String]) {
        items = imageUrls.map { URL(string: $0) }.compactMap { $0 }.map { imageUrl in
            GalleryItem.image { imageCompletion in
                // Nukeのモジュールで非同期に画像を読み込んでます。
                ImagePipeline.shared.loadImage(with: imageUrl, progress: nil, completion: { (response, error) in
                    imageCompletion(response?.image) // 読み込んだ画像をImageViewerに渡してます
                })
            }
        }
    }
    // 何個表示するか
    func itemCount() -> Int {
        return items.count
    }
    // 実際に表示する画像を指定
    func provideGalleryItem(_ index: Int) -> GalleryItem {
        return items[index]
    }
}

あとは実際に使うViewController側で設定してpresentするだけ

class ViewController: UIViewController {
    private var galleryDelegate: GalleryDelegate?
    override func viewDidLoad() {
        super.viewDidLoad()
        showGallery(imageUrls: ["https://hogehoge.com/hoge.jpg"])
    }

    private func showGallery(imageUrls: [String]) {
        galleryDelegate = GalleryDelegate(imageUrls: imageUrls)
        // configurationに、削除とかshow allとかよけいなボタンを表示しないように設定してます。
        let galleryViewController = GalleryViewController(startIndex: 0, itemsDataSource: galleryDelegate!, configuration: [.deleteButtonMode(.none), .seeAllCloseButtonMode(.none), .thumbnailsButtonMode(.none)])
        galleryViewController.closedCompletion = { [weak self] in
            // 閉じたあとになにか実行したいこと
        }
        galleryViewController.swipedToDismissCompletion = { [weak self] in
            // スワイプで閉じたあとになにか実行したいこと
        }
        present(galleryViewController, animated: true, completion: nil)
    }
}

ちなみに動画を再生したいときとかは、動画用のGalleryItemがあるのでそれを作ってギャラリー表示する配列につっこんであげてください。

let item = GalleryItem.video(
    fetchPreviewImageBlock: { $0(UIImage(named: "2")!) }, // 再生前に表示しとく画像
    videoURL: URL (string: "http://video.dailymail.co.uk/video/mol/test/2016/09/21/5739239377694275356/1024x576_MP4_5739239377694275356.mp4")! // 実際に再生する動画
)
items.append(item)

@mogmetの所感

いい感じに表示できるのでViewerとして使うならこれおすすめです!
ちなみにExampleみると結構configurationあるのでいろいろみてみるといいとおもいます。

mogmet

View Comments