我有一个个人档案图像列表(各种尺寸),我希望每个人都缩小尺寸以适合其视图,但是我不希望它们放大和像素化。相反,我希望小图像保持其分辨率。 我怎样才能做到这一点?
这是我到目前为止一直在使用的(但是它会调整大小):
VStack {
Image(...)
.resizable()
.scaledToFill()
}.frame(width:200, height:200)
答案 0 :(得分:1)
我也没有在API中找到简单的解决方案,因此这是一个看起来很适合我的占位符。工作有点复杂。
通过Xcode 11.2 + / iOS 13.2+进行了测试。
使用演示:
struct DemoImagePlaceholder_Previews: PreviewProvider {
static var previews: some View {
VStack {
ImagePlaceholder(image: Image("icon"), size: CGSize(width: 200, height: 200))
.border(Color.red)
ImagePlaceholder(image: Image("large_image"), size: CGSize(width: 200, height: 200))
.border(Color.red)
}
}
}
解决方案:
struct OriginalImageRect {
var rect: Anchor<CGRect>? = nil
}
struct OriginalImageRectKey: PreferenceKey {
static var defaultValue: OriginalImageRect = OriginalImageRect()
static func reduce(value: inout OriginalImageRect, nextValue: () -> OriginalImageRect) {
value = nextValue()
}
}
struct ImagePlaceholder: View {
let image: Image
let size: CGSize
var body: some View {
VStack {
self.image.opacity(0)
.anchorPreference(key: OriginalImageRectKey.self, value: .bounds) {
OriginalImageRect(rect: $0)
}
}
.frame(width: size.width, height: size.height)
.overlayPreferenceValue(OriginalImageRectKey.self) { pref in
GeometryReader { gp -> Image in
if pref.rect != nil, CGRect(origin: .zero, size: gp.size).contains(gp[pref.rect!]) {
return self.image
} else {
return self.image.resizable() // .fill by default, otherwise needs to wrap in AnyView
}
}
}
}
}