가로 세로 비율을 유지하면서 이미지를 중앙으로 정렬

소개



안녕하세요
이미지를 WKWebView에서 콘텐츠를 중앙으로 옮겨 확대 축소하는 표시를하고 싶어졌습니다만, 구현에 대해 조금 고민했기 때문에 써보고 싶습니다.
※샘플 이미지


요구하는 거동에 대해서



표시 영역(WKWebView)이 각각의 때, 안의 화상은 프레임에 맞추어 확대됩니다.
UIImageView의 Aspect Fit과 같은 동작입니다.



소스 코드



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처럼 이미지가 표시됩니다.



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을 vwvh로 지정하지 않으면 잘 표시되지 않습니다.
HTML을 다음으로 설정
html, body, div, img {
    width: 100%;
    height: 100%;
}



WKWebView와 이미지 사이에 수수께끼 여백이 생기는 문제



이것은, 스크롤 하지 않으면 외형상 문제 없습니다만, 아무래도 여백이 생겨 버립니다.


webView.scrollView.isScrollEnabled = false

스크롤을 OFF하여 대응합니다.

참고로 한 기사


  • WKWebView Apple
  • 좋은 웹페이지 즐겨찾기