AsyncImage с размером заполнителя, соответствующим соотношению сторон и обрезке

Я пытаюсь создать изображение с заполнителем. Со следующими ограничениями...

  1. Изображение-заполнитель может иметь не то же соотношение сторон, что и изображение .
  2. Удаленное изображение может не иметь того же соотношения сторон, что и .
  3. Удаленное изображение и изображение-заполнитель могут иметь разные соотношения сторон.
  4. Соотношение сторон фиксировано.

Требования...

  1. Заполнитель и удаленное изображение должны быть масштабированы, чтобы соответствовать соотношению сторон файла .
  2. Их нельзя сдавливать.
  3. Их необходимо обрезать, чтобы они не выходили за границы (задаваемые соотношением сторон).

В моей голове это должно быть просто.

Но я просто не могу заставить это работать без нарушения хотя бы одного из требований.

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

Вы можете вставить это в Xcode, и он покажет

      import SwiftUI

let aspect = 1.5

struct TestView: View {
    var body: some View {
        AsyncImage(
            url: URL(string: "https://placekitten.com/1920/1080"),
            transaction: .init(animation: .easeIn(duration: 3)) // <- slow animation to show issue
        ) { phase in
            switch phase {
            case .success(let image):
                image
                    .resizable()
                    .scaledToFill()
                    .aspectRatio(aspect, contentMode: .fill)
                    .clipped()

            default:
                Image(systemName: "rectangle")
                    .resizable()
                    .scaledToFill()
                    .aspectRatio(aspect, contentMode: .fill)
                    .clipped()
                    .foregroundColor(.white)
            }
        }
        .aspectRatio(aspect, contentMode: .fill)
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            TestView()
                .overlay {
                    // This overlay shows the correct rect but the image is just not cclipped.
                    Color.black
                        .opacity(0.5)
                        .aspectRatio(aspect, contentMode: .fit)
                }
                .padding()
                .aspectRatio(aspect, contentMode: .fit)
        }
        .background(Color.red)
        .padding()
    }
}

Это дает мне следующее...

Красный фон взят из VStack. Черное прозрачное наложение показывает соотношение сторон, которое мне нужно, исходя изaspectустановить в верхней части файла.

1 ответ

Вы пытались использовать программу чтения геометрии, чтобы установить высоту и ширину контейнера изображения?

Вы можете использовать это, чтобы определить необходимое соотношение. Именно такой подход я бы выбрал.

Другие вопросы по тегам