8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftUIでSVG画像を表示する方法

Last updated at Posted at 2023-12-05

Globeeアドベントカレンダー6日目の記事です。
2日連続になっちゃいましたが、本日は簡単な内容になります。
簡単なんですが、意外とこの内容の記事は見当たらなかったので、置いておきます。

背景

SwiftUI.Imageは現在のところSVG形式の画像を十分にサポートしていないため、実装方法を模索している方も多いのではないでしょうか?
特に、SVGファイル側で定義されているキャンパスのサイズよりも大きくリサイズした場合に、画像が粗くなってしまう問題があります。
今回の記事では、UIKitのUIImageViewを利用してこの問題を解決する方法を共有します。
以下が結果のスクリーンショットです。

before after
b.png スクリーンショット 2023-11-02 15.53.00.png

前提

以下が今回利用するSVG画像の定義の一部です。

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
...

このようにviewBoxが24pxということで定義されています。
今回これを150x150にリサイズして利用しているので、実はこのキャンパスサイズを150にすることでも解決できます。

Globeeの開発チームではFigmaから自動的にアイコン定義を抜き出すツールを開発しているので、あまりこの定義を変えたくはないというのがあります。
というかベクター画像なんだからサイズ定義は気にせず扱いたいですよね。
というわけでsvgの定義はこのままで拡大可能にする実装の紹介です。

ちなみにFigmaのAPIでサポートされている画像出力形式は現在以下の通りのようです。

A string enum for the image output format, can be jpg, png, svg, or pdf

ステップ1: UIImageViewをSwiftUIで利用する

UIViewRepresentableプロトコルを採用することで、UIKitのUI部品をSwiftUIで使用することができます。以下はUIImageViewをSwiftUIで利用するためのScalableImageViewというカスタムビューの実装です:

import SwiftUI

struct ScalableImageView: UIViewRepresentable {
    let image: UIImage
    
    init(_ image: UIImage) {
        self.image = image
    }

    func makeUIView(context: Context) -> UIImageView {
        let imageView = UIImageView(image: image)
        imageView.contentMode = .scaleAspectFit
        return imageView
    }
    
    func updateUIView(_ uiView: UIImageView, context: Context) {
        uiView.image = image
    }
}

ステップ2: SwiftUIビューでSVGを表示

最後に、以下のようにScalableImageViewを使用してSVG画像を表示します:

struct ContentView: View {
    var body: some View {
        ScalableImageView(UIImage(named: "iconSpeaker")!)
            .frame(width: 150, height: 150)
    }
}

まとめ

いかがだったでしょうか?記事にするほどのことでもなかったでしょうか。
SVGImageのようなライブラリもあるようですが、このようにUIKitの良さを活かす形で簡単にSVGに対応することができます。
将来的にSwiftUIがSVGのネイティブサポートを追加することを期待しつつ、現時点ではこの方法を活用することでプロジェクトにSVG画像を取り入れることができますね。

Globeeアドベントカレンダー、明日は @LyW による「Exploring Altair: The Rising Star in Data Visualization」です。
よろしくお願いします。

採用情報

現在株式会社Globeeではエンジニア採用を積極的に行っています。
まずはカジュアル面談にて弊社の「教育」にかける思いや「ものづくり」の考え方についてお話できればと思いますので、皆様お気軽にご応募ください。
https://globee.notion.site/Globee-d184eefc3561480292481299c64b04bc

8
3
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
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?