[英]Constraint-based layout of images in a list in SwiftUI
I want to achieve the following constraint-based layout of images in a SwiftUI
List
:我想在SwiftUI
List
中实现以下基于约束的图像布局:
Image
to the list margins (adapts to screen size)将每个Image
的左/右边缘固定到列表边距(适应屏幕尺寸)What I have tried and doesn't work (based on this article ):我尝试过但不起作用的方法(基于这篇文章):
struct MyView: View {
@ObservedObject var viewModel: MyViewModel
let aspectRatio = CGSize(width: 345, height: 120)
var body: some View {
List {
ForEach(viewModel.items) { item in
GeometryReader { geo in
Image("test_image")
.resizable()
.aspectRatio(aspectRatio, contentMode: .fill)
.frame(width: geo.size.width)
.clipped()
}
}
}
}
}
The size I get from geo
is (343, 32) on iPhone 11 Pro.我在 iPhone 11 Pro 上从geo
获得的尺寸是 (343, 32)。 Width makes sense but it's not letting the cells expand beyond a height of 32 for some reason.宽度是有道理的,但由于某种原因,它不会让单元格扩展超过 32 的高度。 Any tips welcome because I'm really starting to miss auto layout constraints.欢迎任何提示,因为我真的开始怀念自动布局约束。
No need to use GeometryReader
for something like this.不需要使用GeometryReader
这样的事情。 For the fixed height, you can just supply a frame
with height
only.对于固定高度,您可以只提供一个仅具有height
的frame
。 You also don't need to create your own let aspectRatio = CGSize(width: 345, height: 120)
- if you leave it nil (by default) it should be fine.您也不需要创建自己的let aspectRatio = CGSize(width: 345, height: 120)
- 如果您将其保留为 nil(默认情况下)应该没问题。
Edit: Using padding
instead of VStack
with spacing编辑:使用padding
而不是带间距的VStack
struct MyView: View {
var body: some View {
List {
ForEach(0..<10, id: \.self) { item in
Image("test_image")
.resizable()
.aspectRatio(contentMode: .fill) /// no need for custom aspect ratio
.frame(height: 120) /// fixed height of image
.clipped() /// stop image from overflowing
.padding(.vertical, 12) /// extra vertical padding
}
}
}
}
Result (with "test_image" ):结果(带有"test_image" ):
However, this has a fixed height of 120
, so the top and bottom of the images are cropped out.但是,它的高度固定为120
,因此图像的顶部和底部都被裁剪掉了。 To fix this, you can just avoid frame
and clipped
altogether.要解决此问题,您可以完全避免frame
和clipped
。
struct MyView: View {
var body: some View {
List {
ForEach(0..<10, id: \.self) { item in
Image("test_image")
.resizable()
.aspectRatio(contentMode: .fill) /// doesn't matter if it's fit or fill
.padding(.vertical, 12) /// extra vertical padding
}
}
}
}
Result:结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.