Globeeアドベントカレンダー6日目の記事です。
2日連続になっちゃいましたが、本日は簡単な内容になります。
簡単なんですが、意外とこの内容の記事は見当たらなかったので、置いておきます。
背景
SwiftUI.Image
は現在のところSVG形式の画像を十分にサポートしていないため、実装方法を模索している方も多いのではないでしょうか?
特に、SVGファイル側で定義されているキャンパスのサイズよりも大きくリサイズした場合に、画像が粗くなってしまう問題があります。
今回の記事では、UIKitのUIImageView
を利用してこの問題を解決する方法を共有します。
以下が結果のスクリーンショットです。
before | after |
---|---|
前提
以下が今回利用する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