Измените размер изображения до ширины экрана с помощью Vstack, сохранив соотношение сторон

Я работаю с VStack показать изображение (их будет несколько разных размеров от json)

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

Мое мнение:

struct ContentView: View {
    var body: some View {

        VStack {

            GeometryReader { geometry in
                VStack {
                    Text("Width: \(geometry.size.width)")
                    Text("Height: \(geometry.size.height)")

                }
                    .foregroundColor(.white)

            }
                .padding()
                .frame(alignment: .topLeading)
                .foregroundColor(Color.white) .background(RoundedRectangle(cornerRadius: 10) .foregroundColor(.blue))
                .padding()

            GeometryReader { geometry in
                VStack {
                    Image("sample")
                    .resizable()

                     //.frame(width: geometry.size.width)
                     .aspectRatio(contentMode: .fit)

                }
                    .foregroundColor(.white)

            }

                .frame(alignment: .topLeading)
                .foregroundColor(Color.white) .background(RoundedRectangle(cornerRadius: 10) .foregroundColor(.blue))
                .padding()



        }
        .font(.title)

    }
}

Когда я использую .frame (width: geometry.size.width) назначив ширину geometry, ширина отображается на весь экран, но высота не поддерживает соотношение сторон. (выглядит подавленным)

Как я могу получить размеры изображения и его пропорции для использования с .aspectRatio (myratio, contentMode: .fit)

Есть еще один способ правильно отобразить изображение, любые предложения

1 ответ

Вам нужно исключить второй GeometryReader, потому что иметь двух детей в VStack что оба принимают столько места, сколько им предлагается, сделает VStack не в состоянии дать Image правильное количество места.

Вам также необходимо повысить приоритет макета Image таким образом VStack сначала предлагает ему место, поэтому он может занимать столько, сколько ему нужно.

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            GeometryReader { geometry in
                VStack {
                    Text("Width: \(geometry.size.width)")
                    Text("Height: \(geometry.size.height)")
                }.foregroundColor(.white)
            }.padding()
                .background(
                    RoundedRectangle(cornerRadius: 10)
                        .foregroundColor(.blue))
                .padding()
            Image(uiImage: UIImage(named: "sample")!)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .layoutPriority(1)
        }
    }
}

import PlaygroundSupport
let host = UIHostingController(rootView: ContentView())
host.preferredContentSize = .init(width: 414, height: 896)
PlaygroundPage.current.liveView = host

Результат:

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