画面幅の注意 スマホアプリのWebView高さ再現 フロントエンド定例 2022/9/9

igarashisho|2022年09月09日
フロントエンド

こんにちは、フロントエンドチームの @syo_igarashi です。
今週のフロントエンド定例の内容を記載します。

フロントエンド定例について、以前の記事(ランサーズのフロントエンドチームが取り組んでいること)でお伝えしたのですが、毎週金曜日に開催しており、実際の業務で取り組んでいることや気になった技術情報等をシェアしあう会になっています。

以下、今週の内容です。

画面幅の注意 スマホアプリのWebView高さ再現

現在モーダルの実装を進めていてたまたまスマホアプリ内でも確認することがあったので画面幅について気づいたことを記載します。

Chromeの開発ツールでもスマホサイト用に表示の切り替えが可能です。

 

しかし実際のアプリ上の表示ではiOSでいう時間やバッテリーの表示をしているステータスバー、スマホアプリで使用しているタブなどのナビゲーションバーの高さなどの考慮、アプリ上ではサイト上のヘッダーの表示を行わないなどChromeの開発ツールだけではわからない描画の情報だったりします。

XcodeをインストールしXcodeの機能にある「debug view hierarchy」でWebViewの大きさを調べました。

 

実際にアプリをビルドしてWebViewの幅を調べたところ、

iPhone SE: 375×509 (Chromeでは375×667)
iPhone 12 Pro: 390×625 (Chromeでは390×844)

と数100px単位で高さが異なるのでChromeの表示に合わせて作成するとアプリでみた時に見切れて違和感のある表示になる可能性があります。

レスポンシブの考慮としてどの箇所をoverflow: scrollで表示させるのか、最小であるiPhone SEのWebViewでも問題なく表示できているかの確認が必要そうと思いました。

とはいえ都度スマホアプリで確認するのも大変なので

SwiftUIでスマホアプリのWebViewの高さを適応したデスクトップアプリを作成しました。

ほぼほぼWebViewしか入れてない簡単なデスクトップアプリです。
デスクトップアプリ上はmacOSのWebViewを使用しているのでChromeよりかはスマホアプリ上の表示を再現できていると思います。

作り方を記載すると

Create new Project: macOS Appとして作成

独自のWebViewの処理を記載する

import SwiftUI
import WebKit

struct WebView: NSViewRepresentable {
  let url: URL

  func makeNSView(context: Context) -> WKWebView {
    let webView = WKWebView()
    webView.customUserAgent = "スマホアプリ用に変更 場合によってはheaderを変えるとかもありそう"

    return webView
  }

  func updateNSView(_ nsView: WKWebView, context: Context) {
    nsView.load(URLRequest(url: url))
  }
}

ContentViewにWebViewの指定をする

import SwiftUI
import WebKit

struct ContentView: View {
  @State private var url = "https://lancers.jp"

  var body: some View {
    TextField("URL", text: $url).padding(.top, 16.0)

    HStack {
      VStack {
        // CSS ピクセル 375x667
        Text("iPhone SE")

        if url.isEmpty {
          Text("URLの入力してください")
        } else {
          WebView(url: URL(string: url)!).frame(width: 375.0, height: 509.0)
        }
      }

      VStack {
        // CSS ピクセル 428x926
        Text("iPhone 13 Pro Max")

        if url.isEmpty {
          Text("URLの入力してください")
        } else {
          WebView(url: URL(string: url)!).frame(width: 428.0, height: 707.0)
        }
      }
    }
  }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

WebViewの通信をするのにNetworkの権限が必要なので下記の画像にあるApp Sandbox -> Network -> Outgoing Connections (Client)にチェックを入れます。

これでビルドしてアプリが起動することが確認できたら完成です。

SwiftUIは初めていじってみたのですがstateの扱いがReactっぽく、HStackもVStackも実質flexboxみたいでだいぶViewの扱いがWebフロントに近くなったなぁと思いました。

 

次回の更新予定は、9/16(金)になります!

前回の定例内容はこちらから確認可能ですのでご興味いただければ下記のリンクから閲覧いただければと思います。

https://engineer.blog.lancers.jp/?s=フロントエンド定例