我试图将多个单元格彼此相邻放置,其中每个单元格由下面的图像和文本组成。单元格本身应该是一个正方形,并且应该缩放图像以填充剩余空间(剪切图像的一部分)。
首先,我尝试将图像和下面的文字制作成正方形。现在我的问题是,我不知道如何在 SwiftUI 中正确实现。使用此代码时,我可以让它工作:
VStack {
Image(uiImage: recipe.image!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 200, height: 200, alignment: .center)
.clipped()
Text(recipe.name)
}
Run Code Online (Sandbox Code Playgroud)
问题是,我必须指定一个固定的帧大小。我想要的是一种制作单元格的方法,它保持 1:1 的纵横比并且可以调整大小,因此我可以将它们的动态数量放在彼此相邻的屏幕上。
我也尝试使用
VStack {
Image(uiImage: recipe.image!)
.resizable()
.aspectRatio(1.0, contentMode: .fit)
.clipped()
Text(recipe.name)
}
Run Code Online (Sandbox Code Playgroud)
这给了我方形图像,动态缩放。但问题是,图像现在被拉伸以填充正方形而不是缩放以填充它。
我的下一个想法是把它剪成方形。为此,我首先尝试将其剪成圆形(因为显然没有方形):
VStack {
Image(uiImage: recipe.image!)
.resizable()
.aspectRatio(1.0, contentMode: .fit)
.clipped()
Text(recipe.name)
}
Run Code Online (Sandbox Code Playgroud)
但是出于某种奇怪的原因,它并没有真正剪辑图像,而是保留了剩余的空间......
那么我是不是没有看到任何东西,或者是将图像裁剪成框架修改器的唯一选项?
澄清:我不太关心文本,因为整个单元格(或者图像更简单)是方形的,无需通过.frame非方形原始图像指定其大小,也无需拉伸非方形原始图像以使其成为合身。
所以完美的解决方案是 VStack 是方形的,但获得方形图像也可以。它应该看起来像图像 1,但不必使用.frame修饰符。
eth*_*ooo 22
ZStack 将通过允许我们分层视图而不影响另一个布局来帮助解决这个问题。
对于文本:
.frame(minWidth: 0, maxWidth: .infinity) 将文本水平扩展到其父级的大小
.frame(minHeight: 0, maxHeight: .infinity) 在其他情况下很有用
至于图像:
.aspectRatio(contentMode: .fill) 使图像保持其纵横比而不是压缩到其框架的大小。
.layoutPriority(-1)降低布局图像的优先级以防止其扩展其父级(在我们的情况下为ZStack内ForEach)。
的值layoutPriority只需要低于默认设置为 0 的父视图。我们必须这样做,因为 SwiftUI 会在其父级之前布局子级,并且父级必须处理子级大小,除非我们手动设置不同的优先级。
的.clipped()改性剂使用的边界框以掩蔽视图所以你需要将其设置为剪辑尚未1的任何图像:1分的纵横比。
var body: some View {
HStack {
ForEach(0..<3, id: \.self) { index in
ZStack {
Image(systemName: "doc.plaintext")
.resizable()
.aspectRatio(contentMode: .fill)
.layoutPriority(-1)
VStack {
Spacer()
Text("yes")
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.white)
}
}
.clipped()
.aspectRatio(1, contentMode: .fit)
.border(Color.red)
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:虽然几何阅读器非常有用,但我认为应该尽可能避免使用它们。让 SwiftUI 来完成工作更干净。这是我最初的解决方案,Geometry Reader它也同样有效。
HStack {
ForEach(0..<3, id: \.self) { index in
ZStack {
GeometryReader { proxy in
Image(systemName: "pencil")
.resizable()
.scaledToFill()
.frame(width: proxy.size.width)
VStack {
Spacer()
Text("yes")
.frame(width: proxy.size.width)
.background(Color.white)
}
}
}
.clipped()
.aspectRatio(1, contentMode: .fit)
.border(Color.red)
}
}
Run Code Online (Sandbox Code Playgroud)
ram*_*nok 19
这是我在Reddit上找到的另一个解决方案并进行了一些改进:
Color.clear
.aspectRatio(1, contentMode: .fit)
.overlay(
Image(imageName)
.resizable()
.scaledToFill()
)
.clipShape(Rectangle())
Run Code Online (Sandbox Code Playgroud)
它与 Chads 的答案类似,但不同之处在于相对于清晰颜色(背景与覆盖)放置图像的方式
奖励:让它具有圆形形状只需用作.clipShape(Circle())最后一个修饰符。其他一切保持不变