LoginSignup
5
6

More than 5 years have passed since last update.

Swift4 WKWebViewでローカルやWeb上のgifを再生するカスタムクラス

Last updated at Posted at 2018-07-16

はじめに

こんにちは:leaves:
gifを簡易的に再生したくなりましたが、ライブラリなどを使わずに、WebViewで表示するにはどうするのか気になったので調べてみました。今回はカスタムクラスとして書いてみました。
至らぬ点など多々あると思いますが、コメントなど頂けたら幸いです。

ローカルのgif
hari.gif

Web上のgif
sea.gif

実装について

WKWebViewでの実装では、gifを1度のみ再生したり、途中で止めたりなど細かくは指定できないのかなと思っています...。細かく設定するには、ライブラリの導入を考えてもいいかもしれません。

ソースコード

カスタムクラスとして実装してみました。クラス名などご自由に変更してください。

GifAnimateView.swift
import UIKit
import WebKit

class GifAnimateView: WKWebView {

    private var data: Data?

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.initialize()
    }

    private override init(frame: CGRect, configuration: WKWebViewConfiguration) {
        super.init(frame: frame, configuration: configuration)
        self.initialize()
    }

    convenience init?(fileName: String, origin: CGPoint = CGPoint.zero) {
        guard let url = Bundle.main.url(forResource: fileName, withExtension: "gif") else { return nil }
        guard let gifData = NSData(contentsOf: url) else { return nil }
        guard let image = UIImage(data: gifData as Data) else { return nil }
        self.init(frame: CGRect(origin: origin, size: image.size))
        self.data = gifData as Data
    }

    private func initialize() {
        self.scrollView.isScrollEnabled = false
        self.scrollView.isUserInteractionEnabled = false
    }
    /**
     gifを再生します (infinity animation)
     */
    func startAnimate() {
        guard let data = self.data else { return }
        self.load(data, mimeType: "image/gif", characterEncodingName: "utf-8", baseURL: NSURL() as URL)
    }
    /**
     gif再生を停止し、表示をクリーンします
     */
    func clear() {
        guard let url = URL(string: "about:blank") else { return }
        self.load(URLRequest(url: url))
    }
    /**
     URLからgifをロードします
     */
    static func setGifBy(url: String, origin: CGPoint = CGPoint.zero, completion: @escaping ((GifAnimateView) -> ())) {
        guard let url = URL(string: url) else { return }
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            if error == nil, case .some(let result) = data {
                guard let image = UIImage(data: result as Data) else { return }
                DispatchQueue.main.async {
                    let gifAnimateView = GifAnimateView(frame: CGRect(origin: origin, size: image.size))
                    gifAnimateView.data = result
                    completion(gifAnimateView)
                }
            }
        }
        task.resume()
    }
}

使い方

ローカルのgif
ファイル名を指定してカスタムViewを生成します。

MainViewController.swift
import UIKit
import WebKit

class MainViewController: UIViewController {

    var gifView: GifAnimateView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.gifView = GifAnimateView(fileName: "hari")
        self.view.addSubview(gifView)
        self.gifView.center = self.view.center
    }

    @IBAction func startAction(_ sender: Any) {
        self.gifView?.startAnimate()
    }

    @IBAction func clearAction(_ sender: Any) {
        self.gifView?.clear()
    }
}

Web上のgif
URLを指定してsetByGifすると、読み込み完了時にインスタンスが返ります。

MainViewController.swift
import UIKit
import WebKit

class MainViewController: UIViewController {

    var gifView: GifAnimateView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let sea = "https://qiita-image-store.s3.amazonaws.com/0/128250/76b16142-0542-63a1-d1ae-c911cca4177a.gif"
        GifAnimateView.setGifBy(url: sea) { gifView in
            self.view.addSubview(gifView)
            self.gifView = gifView
            self.gifView.center = self.view.center
        }
    }

    @IBAction func startAction(_ sender: Any) {
        self.gifView?.startAnimate()
    }

    @IBAction func clearAction(_ sender: Any) {
        self.gifView?.clear()
    }
}

参考にさせていただいた記事

5
6
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
5
6