I am working with VStack
to show an image (they will be several with different sizes from a json)
I need to show it to occupy the screen width (the width of the vstack and maintaining aspect ratio) and to be properly resized, respecting the height according to the width of the screen. I have tried in different ways, but I manage to display the image correctly.
My View is:
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)
}
}
When I use .frame (width: geometry.size.width)
by assigning the width of the geometry
, the width is shown to the entire screen but the height is not maintaining aspect ratio. (looks crushed)
How can I get the dimensions of the image and find its proportion to use it with .aspectRatio (myratio, contentMode: .fit)
There is another way to display the image correctly, any suggestions
To resize proportionally: hold the SHIFT key on the keyboard as you click and drag to resize the image or icon proportionally, preserving the width-to-height ratio of the image or icon as you move the corners of the image to enlarge or shrink it.
Image("name"). resizable(). scaledToFit() isn't bugged, though. So you can wrap your image in a view, adjust the frame of the view to whatever size you need, then scaledToFit() will then make the image as big as it can be while keeping aspect ratio.
You need to eliminate the second GeometryReader
, because having two children in the VStack
that both accept as much space as they are offered is going to make the VStack
unable to give the Image
the correct amount of space.
You also need to raise the layout priority of the Image
so that the VStack
offers it space first, so it can take as much as it needs.
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
Result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With