当我们在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如何让我们处理滚动数据 |
---|
赏我一个赞吧~~~