LoginSignup
1
2

More than 3 years have passed since last update.

Image+GeometryReaderを使ってAspectFill + clipToBoundsを再現する

Last updated at Posted at 2020-11-21

https://medium.com/@wendyabrantes/swift-ui-square-image-modifier-3a4370ca561f
こちらの記事を参考に実装しました。

GeometryReader(content: { geometry in
    Image(uiImage: image)
        .resizable()
        .scaledToFill()
        .frame(width: geometry.size.width, height: geometry.size.height)
})
    .aspectRatio(1, contentMode: .fit)

上記の記事との違いはGeometryReader内のImageの属性に.frameでGeometryReaderのsizeを渡しています。Imageにframeを渡すことで、GeometryReaderの表示領域に対してscaledToFillのリサイズが当てられます。よってアスペクト比を固定しつつ中央寄せで任意のアスペクト比でクリップすることができるようになります。

この方法のメリットとして、子要素でサイズが決まるのではなくサイズは親要素側で提供された表示可能領域にあわせてリサイズするのでLazyVGridなどで使用する際などにサイズを固定化する必要がなくなります。

サンプルコード

gist

struct ProductGridCell: View {
    let name: String
    let price: Int
    let image: UIImage
    var body: some View {
        VStack(alignment: .leading, spacing: 3) {
            GeometryReader(content: { geometry in
                Image(uiImage: image)
                    .resizable()
                    .scaledToFill()
                    .frame(width: geometry.size.width, height: geometry.size.height)
            })
            .aspectRatio(1, contentMode: .fit)
            .clipShape(RoundedRectangle(cornerRadius: 4))
            Text(name)
                .foregroundColor(.primary)
                .font(.caption)
            Text(\(price)")
                .font(.caption2)
                .foregroundColor(.secondary)
        }
    }
}

struct ProductGridCell_Previews: PreviewProvider {
    static var previews: some View {
        ScrollView {
            LazyVGrid(columns: [GridItem(), GridItem(), GridItem()], content: {
                ForEach(0..<20) { _ in
                    ProductGridCell(name: "どら焼き", price: 300, image: UIImage(imageLiteralResourceName: "product"))
                }
            })
                .padding()
        }
    }
}

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