SwiftUI:使用GeometryReader调整图片大小以适应屏幕

当我们在SwiftUI中创建一个Image视图时,它会根据内容的大小自动调整自己的大小。所以,如果图片是1000x500,那么Image视图也是1000x500。有时这是您想要的,但大多数情况下,您需要以较低的大小显示图像,我想向您展示如何做到这一点,以及如何使用名为GeometryReader的新视图类型使图像适合用户屏幕的宽度。

首先,在项目中添加某种图片。不管是什么,只要比屏幕宽就行。我称我的为“Example”,但显然您应该在下面的代码中替换您的图片名称。

现在让我们在屏幕上绘制该图像:

struct ContentView: View {
    var body: some View {
        VStack {
            Image("Example")
        }
    }
}

即使在预览中,你也可以看到这对于可用空间来说太大了。Image与其他视图具有相同的frame()修饰符,因此您可以尝试按如下方式缩小它:

Image("Example")
    .frame(width: 300, height: 300)

然而,这是行不通的——你的图片将仍然是它的完整大小。如果你想知道为什么,仔细看看预览窗口:你会看到你的图像是全尺寸的,但现在有一个蓝色的盒子是300×300,显示在中间。Image视图的frame已正确设置,但图像的内容仍显示为其原始大小。

尝试将图像更改为:

Image("Example")
    .frame(width: 300, height: 300)
    .clipped()

现在你会看得更清楚:我们的图像视图确实是300x300,但这并不是我们真正想要的。
如果还希望调整图像内容的大小,我们需要使用resizable()修饰符,如下所示:

Image("Example")
    .resizable()
    .frame(width: 300, height: 300)

那很好。是的,现在图像的大小调整正确了,但可能看起来被压扁了。我的图像不是正方形的,所以它看起来扭曲了,现在它已经调整成正方形。

要解决这个问题,我们需要要求图像按比例调整自身大小,这可以使用aspectRatio()修饰符来完成。这让我们可以提供一个精确的长宽比以及它应该如何应用,但是如果我们跳过长宽比本身,SwiftUI将自动使用原始的长宽比。

当谈到“如何应用”部分时,SwiftUI将其称为“内容模式”,并为我们提供了两个选项:.fit意味着即使这意味着视图的某些部分为空,整个图像也将适合容器;.fill意味着视图将没有空部分,即使这意味着我们的某些图像位于容器之外。

两种方法都试试看你自己有什么不同。这是使用.fit模式:

Image("Example")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: 300, height: 300)

这是.fill模式:

Image("Example")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 300, height: 300)

如果我们需要固定大小的图像,所有这些都很有用,但通常您需要自动放大的图像,以在一个或两个维度中填充屏幕。也就是说,与其硬编码宽度为300,你真正想说的是“让这个图像填满屏幕的宽度”

SwiftUI为此提供了一种专用的类型,称为GeometryReader,它的功能非常强大。是的,我知道许多SwiftUI功能强大,但老实说:使用GeometryReader可以做什么会让您大吃一惊。

我们将在项目15中更详细地介绍GeometryReader,但现在,我们将其用于一项工作:确保图像填充其容器视图的整个宽度。

与我们使用的其他视图一样,GeometryReader是一个视图,除了在创建视图时,我们将获得一个GeometryProxy对象以供使用。这使我们可以查询环境:容器有多大?我们的在视图中的位置是什么?是否有安全区域?等等。

我们可以使用此几何代理设置图像的宽度,如下所示:

VStack {
    GeometryReader { geo in
        Image("Example")
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: geo.size.width, height: 300)
    }
}

现在,无论我们使用什么设备,图像都将占据我们屏幕的整个宽度。

对于最后一个技巧,让我们从图像中删除height,如下所示:

VStack {
    GeometryReader { geo in
        Image("Example")
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: geo.size.width)
    }
}

我们为SwiftUI提供了足够的信息,它可以自动计算出高度:它知道原始宽度,知道我们的目标宽度,并且知道我们的内容模式,因此它了解图像的目标高度如何与图像的目标宽度成比例。

译自 Resizing images to fit the screen using GeometryReader

iExpense 项目挑战 Hacking with iOS: SwiftUI Edition SwiftUI:ScrollView如何让我们处理滚动数据

赏我一个赞吧~~~

你可能感兴趣的:(SwiftUI:使用GeometryReader调整图片大小以适应屏幕)