Goal
I often have the case where I want to scale an image so that it fills its container proportionally without modifying its frame. An example is seen in the first screenshot below. The container view has a fixed frame as indicated by the red border. The image itself has a different aspect ratio. It's scaled to fill the entire container, but it still has the same frame as the container and thus does not affect the container's layout (size).
My Solution
I used the following code to accomplish this:
struct ContentView: View {
var body: some View {
ImageContainerView()
.frame(width: 300, height: 140)
.border(.red, width: 2)
}
}
struct ImageContainerView: View {
var body: some View {
GeometryReader { geometry in
Image("image")
.resizable()
.aspectRatio(contentMode: .fill)
.border(.blue, width: 2)
.frame(width: geometry.size.width, height: geometry.size.height)
.clipped()
}
}
}
Problem
As you can see, I used a geometry reader to manually set the image's frame to match the parent view's frame. This feels a bit superfluous as the image already receives this information implicitly as the proposed size from its parent view. However, if I don't use the geometry reader this way, the image is not clipped and its frame matches the full scaled image, not the parent view's frame. This is shown in the second screenshot below.
Question
Is there a (more "native") way in SwiftUI to achieve the desired behavior without using a geometry reader?