アスペクト比を保ったまま画像を中央寄せ 拡大縮小をするWKWebViewのExtension

# はじめに
こんにちは:leaves:
画像をWKWebViewにて、コンテンツを**中央寄せ**,**拡大縮小**する表示をしたくなりましたが、実装について少し悩んだので書いて見たいと思います。
※サンプル画像
<img src='https://qiita-image-store.s3.amazonaws.com/0/128250/39dd69dc-0c04-5de2-4e36-e6937c82c5ca.jpeg' width='200'>

# 求める挙動について
表示領域(**WKWebView**)がそれぞれの時、中の画像は枠に合わせて拡大されます。
**UIImageView**の**Aspect Fit**のような動作です。

<img width="599" alt="screen.png" src="https://qiita-image-store.s3.amazonaws.com/0/128250/3314d65f-0f6d-84bb-7a51-c614e7acc4d4.png">

# ソースコード
## HTML
```html
<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <style type='text/css'>
    * {
        margin: 0;
        padding: 0;
    }
    html, body, div, img {
        width: 100vw;
        height: 100vh;
    }
    div {
        display: flex;
        align-items: center;
        justify-content: center;
    }
    img {
        object-fit: contain;
        background-color: lightgray;
    }
  </style>
</head>
<body>
  <div><img src='https://qiita-image-store.s3.amazonaws.com/0/128250/39dd69dc-0c04-5de2-4e36-e6937c82c5ca.jpeg'></div>
</body>
</html>
```

## WKWebView Extension
```WKWebViewExt.swift
import WebKit

extension WKWebView {
    /**
     png画像, jpeg画像, gif画像をURLからロードします
     各画像はAspectFitで表示されます.
     - parameters:
        - url: ロードするアセットURL
        - imageBackgroundColor: 画像と枠の間のマージンがあった場合の背景色
     */
    func setImageBy(url: URL, imageBackgroundColor: UIColor = UIColor.white) {
        let html = "<!DOCTYPE html><html><head><meta charset='utf-8'><style type='text/css'>* {margin: 0;padding: 0;}html, body, div, img {height: 100vh;width: 100vw;}div {display: flex;align-items: center;justify-content: center;}img {object-fit: contain;background-color: #\(imageBackgroundColor.hex);}</style></head><body><div><img src='\(url.absoluteString)'></div></body></html>"
        loadHTMLString(html, baseURL: nil)
    }
}

extension UIColor {
    var hex: String {
        var r: CGFloat = 0
        var g: CGFloat = 0
        var b: CGFloat = 0
        var a: CGFloat = 0
        
        getRed(&r, green: &g, blue: &b, alpha: &a)
        
        let rgb = (Int)(r*255) << 16 | (Int)(g*255) << 8 | (Int)(b*255) << 0
        
        return String(format: "%06x", rgb)
    }
}
```

# 使い方
WKWebView表示領域からUIImageViewのAspectFitのように画像が表示されます。

<img src='https://qiita-image-store.s3.amazonaws.com/0/128250/cad77328-ad25-e2f6-86c1-f85879fb8558.png' width='200'>

```MainViewController.swift
import UIKit
import WebKit

class MainViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // WKWebViewの作成
        let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: 200, height: 300))
        //スクロールを拒否
        webView.scrollView.isScrollEnabled = false
        // borderをつける
        webView.layer.borderColor = UIColor.black.cgColor
        webView.layer.borderWidth = 1
        //URLから画像を設定
        webView.setImageBy(url: URL(string: "https://qiita-image-store.s3.amazonaws.com/0/128250/39dd69dc-0c04-5de2-4e36-e6937c82c5ca.jpeg")!, imageBackgroundColor: UIColor.lightGray)
        self.view.addSubview(webView)
        //センタリング
        webView.center = self.view.center
    }
}
```

# 気になったところ
## vw vh を利用しないと画像が全て表示されない問題
WKWebViewだと、htmlを`vw`と`vh`で指定しないとうまく表示されません。
HTMLを以下に設定

```html
html, body, div, img {
    width: 100%;
    height: 100%;
}
```

<img src='https://qiita-image-store.s3.amazonaws.com/0/128250/6f26dbcd-f1be-ad03-e721-2d7630f3bd11.png' width='200'>

## WKWebViewと画像の間に謎の余白ができてしまう問題
これは、スクロールしなければ見た目上問題ないのですが、どうしても余白ができてしまいます。

<img src='https://qiita-image-store.s3.amazonaws.com/0/128250/c79aa7fb-294f-a681-2f61-9389261bd8f4.png' width='200'>

```swift
webView.scrollView.isScrollEnabled = false
```

スクロールをOFFして、対応します。

# 参考にさせていただいた記事
- [WKWebView
 Apple](https://developer.apple.com/documentation/webkit/wkwebview)