2
2

【SwiftUI】画像の元のアスペクト比を保ちつつ、Viewのアスペクト比を変えたい!In LazyVGrud!

Last updated at Posted at 2023-11-29

はじめに

SwiftUI楽しいです!むらおです!
LazyVGrid内で、画像のアスペクト比を保ったまま画像のViewの比率を指定したい!ただ、frameモディファイアは使いたくない!という状況に陥り、実装に手こずったので備忘録として残しておきます!

想定する画面

以下のようなデザインを想定しています。

  • 画像のアスペクト比は1:1
  • 画像の枠のアスペクト比は2:1(横:縦 = 2:1)
  • 見切れるのは構わない → scaleはfill
  • 使用する画像はこちら
  • かわいい

案1(ボツ)

ImageにaspectRatioを指定し、frameモディファイアで無理やり縛る

LazyVGrid(
    columns: .init(repeating: .init(.flexible()), count: 2),
    spacing: 12
){
    ForEach(1...10, id: \.self) { _ in
        VStack(alignment: .leading, spacing: 4) {
            Text("画像")
            Image("catImage")
                .resizable()
                .aspectRatio(1, contentMode: .fill)
                .frame(width: 140, height: 70)
                .clipShape(RoundedRectangle(cornerRadius: 4))
        }
        .padding()
        .border(Color.gray)
    }
}

一見上手くいくように見えますが、frameを指定しているので端末によって見え方が異なってしまいます。
例えば、iPadで見るとかなり小さく見えます。(frame指定なしだと画像がはみ出てしまいます)

これを回避するためにはGeometryReaderを使ってセルの幅や高さを計算することになりそうです。
(めんどくさいのでなし)
う〜〜ん、不採用!

案2(採用)

LazyVGrid(
    columns: .init(repeating: .init(.flexible()), count: 2),
    spacing: 12
){
    ForEach(1...10, id: \.self) { _ in
        VStack(alignment: .leading, spacing: 4) {
            Text("画像")
            RoundedRectangle(cornerRadius: 4)
                .aspectRatio(2, contentMode: .fit)
                .overlay {
                    Image("catImage")
                        .resizable()
                        .scaledToFill()
                }
                .clipShape(RoundedRectangle(cornerRadius: 4))
        }
        .padding()
        .border(Color.gray)
    }
}

RoundedRectangleにアスペクトを指定し、overlayImageを重ね、はみ出た部分をカットする方法でうまく行きました。
clipShapeclippedを使うことではみ出た部分をカットできますね。overlayにつけるのがミソです。(Imageの下につけると上手くいかない)
今回はRoundedRectangleを使用しましたが、Colorでも同じことが可能だと思います。

今回の実装だと、columnsのcountを変えるだけで色々レイアウトを変更できるので、かなり良く見えるのではないでしょうか
採用!

参考記事

【SwiftUI】LazyVGrid内の画像を正方形にする【ワークアラウンド】

2
2
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
2
2