Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

こんにちは: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()
    }
}

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした