Уменьшать, но не увеличивать изображение SwiftUI - PullRequest
1 голос
/ 23 марта 2020

У меня есть список изображений профиля (разных размеров), которые я хочу, чтобы каждое из них уменьшалось, чтобы соответствовать его виду, но я не хочу, чтобы они были увеличены и были расточены. Вместо этого я хочу, чтобы маленькие изображения оставались с разрешением, в котором они находятся. Как мне этого добиться?

Это то, что я использовал до сих пор (но его размер увеличивается):

VStack {        
    Image(...)
         .resizable()
         .scaledToFill()
}.frame(width:200, height:200)

1 Ответ

1 голос
/ 23 марта 2020

Я также не нашел простого решения в API, поэтому вот заполнитель, который мне подходит. Это немного усложняется работами.

Протестировано с Xcode 11.2+ / iOS 13.2 +.

demo

Демонстрация использования:

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
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...