缩小但不放大SwiftUI映像

缩小但不放大SwiftUI映像,swiftui,Swiftui,我有一个配置文件图像列表(各种大小),我希望每个图像缩小以适应其视图,但我不希望它们被放大和像素化。相反,我希望小图像保持其当前的分辨率。 我怎样才能做到这一点 这是我到目前为止一直在使用的(但它会调整大小): 我也没有在API中找到简单的解决方案,所以这里有一个占位符,看起来很适合我。这是一个有点复杂的工作 使用Xcode 11.2+/iOS 13.2+进行测试 用法演示: struct DemoImagePlaceholder_Previews: PreviewProvider {

我有一个配置文件图像列表(各种大小),我希望每个图像缩小以适应其视图,但我不希望它们被放大和像素化。相反,我希望小图像保持其当前的分辨率。 我怎样才能做到这一点

这是我到目前为止一直在使用的(但它会调整大小):


我也没有在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
                }
            }
        }
    }
}
struct OriginalImageRect{
var rect:锚?=nil
}
struct OriginalImageRectKey:PreferenceKey{
静态变量defaultValue:OriginalImageRect=OriginalImageRect()
静态函数reduce(值:inout OriginalImageRect,nextValue:()->OriginalImageRect){
value=nextValue()
}
}
结构图像占位符:视图{
让图像:图像
让大小:CGSize
var body:一些观点{
VStack{
self.image.opacity(0)
.AnchorReference(键:OriginalImageRectKey.self,值:。边界){
OriginalImageRect(rect:$0)
}
}
.框架(宽度:尺寸.宽度,高度:尺寸.高度)
.overlayPreferenceValue(OriginalImageRectKey.self){pref in
GeometryReader{gp->中的图像
如果pref.rect!=nil,则CGRect(原点:.0,大小:gp.size)。包含(gp[pref.rect!){
回归自我形象
}否则{
默认情况下返回self.image.resizeable()/.fill,否则需要在AnyView中换行
}
}
}
}
}
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
                }
            }
        }
    }
}