使用`Vstack`将图像调整为屏幕宽度并保持纵横比

6

我正在使用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)一起使用

还有另一种方法可以正确显示图像,您有什么建议吗?

image


不确定这是否有效,但您是否尝试将宽度设置为“无限”(.infinite)? - user7014451
最后一个想法 - 我稍后会看看是否还有其他的东西。你试过改变修饰符的顺序吗?特别是第二个。 (我们都知道resizable必须放在aspectRatio之前。你试过让frame成为第三个修饰符吗? - user7014451
@KB-YYZ 宽度fill不保持纵横比。Vstack宽度已满,但不遵守比例--> https://i.stack.imgur.com/VWWPk.jpg - Mario Burga
好的,让我们举个具体的例子。一个设备是1000h x 1000w,一张图片是500h x 200w。也就是说,一个设备将会在使用UIKit术语中的aspectFit时,正常显示为1000h x 400w。你是想要将图片大小调整为2500h x 1000w吗?虽然这是可行的,但显然这不是aspectFit的意思。此外,你的屏幕截图在我看来似乎是aspectFill,而你的代码并没有表现出来。 - user7014451
@dfd 这些图片来自于一个 json 文件,并且它们的尺寸不同。我有一个事件列表,点击其中一个事件会跳转到名为 DetailsEvent.swift 的视图(在这里显示的图片尺寸并不相同,它们是多样化的)。请参见 gif:https://i.imgur.com/GZhACWH.gif - Mario Burga
显示剩余4条评论
1个回答

6

您需要消除第二个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

结果:

playground result


1
.layoutPriority(1) 对我很有效,谢谢! - lazarevzubov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接