如何缩放图像以填充父视图而不影响 SwiftUI 中的布局?

Mis*_*cha 8 image clipping aspect-ratio swiftui geometryreader

目标

我经常遇到这样的情况:我想要缩放图像,以便它按比例填充其容器而不修改其框架。下面的第一个屏幕截图中显示了一个示例。容器视图具有固定框架,如红色边框所示。图像本身具有不同的长宽比。它被缩放以填充整个容器,但它仍然具有与容器相同的框架,因此不会影响容器的布局(大小)。

我的解决方案

我使用以下代码来完成此操作:

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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题

如您所见,我使用几何读取器手动设置图像的框架以匹配父视图的框架。这感觉有点多余,因为图像已经从其父视图隐式接收到此信息作为建议的大小。但是,如果我不以这种方式使用几何读取器,则图像不会被剪切,并且其框架与完整缩放的图像匹配,而不是父视图的框架。下面的第二个屏幕截图显示了这一点。

问题

SwiftUI 中是否有一种(更“原生”)的方法可以在不使用几何读取器的情况下实现所需的行为?

剪裁的 未修剪的

vac*_*ama 18

这是一种不使用GeometryReader. 通过使图像成为.overlay()另一个视图的图像,该视图可以使用修饰符处理裁剪.clipped()

struct ContentView: View {
    var body: some View {
        ImageContainerView()
            .frame(width: 300, height: 140)
            .border(.red, width: 2)
    }
}

struct ImageContainerView: View {
    var body: some View {
        Color.clear
            .overlay (
                Image("image")
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .border(.blue, width: 2)
            )
            .clipped()
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,传入name图像的 ,以便ImageContainerView与其他图像重用。