How to Set Width and Height of an Image in Swiftui

How to resize Image with SwiftUI?

You should use .resizable() before applying any size modifications on an Image.

Image(room.thumbnailImage)
.resizable()
.frame(width: 32.0, height: 32.0)

How to set width and height of an image in SwiftUI?

Try this

Image("testImg")
.resizable()
.frame(width: 50.0, height: 50.0)

Can I change image size in Swift UI

Maybe Image("jojologo-yellow").resizable().frame(width: 30.0, height: 30.0) is what you are looking for?

SwiftUI Image with high height layout

Ok, I found a way

Color.clear
.background(Image("image")
.resizable()
.scaledToFill())
.clipped()

Embedding the image as background of a clear Color, the image is limited to the parent size!

Result: https://imgur.com/a/ceZRqSw

How to scale a SwiftUI Image including its overlay?

Then like this with GeometryReader:

struct ContentView: View {

let imageSize = CGSize(width: 150, height: 150) // Size of orig. image
let logoPos = CGSize(width: 10, height: 120) // Position of Logo in relation to orig. image
let logoSize = CGSize(width: 20, height: 20) // Size of logo in relation to orig. image

@State private var contentSize = CGSize.zero

var body: some View {

Image("dog")
.resizable()
.scaledToFit()

.overlay(
GeometryReader { geo in
Color.clear.onAppear {
contentSize = geo.size
}
}
)
.overlay(
Image(systemName: "circle.hexagongrid.circle.fill")
.resizable()
.foregroundColor(.pink)
.offset(x: logoPos.width / imageSize.width * contentSize.width,
y: logoPos.height / imageSize.height * contentSize.height)
.frame(width: logoSize.width / imageSize.width * contentSize.width,
height: logoSize.height / imageSize.height * contentSize.height)
, alignment: .topLeading)
}
}

SwiftUI: How to find the height of an image and use it to set the size of a frame

If I understood correctly, you want the size of the image so you can use it's dimensions in it's own frame? You could make a function that takes in an image name and returns your desired image while also setting @State vars for the width and height which you can use in the frame.

    @State var width: CGFloat = 0
@State var height: CGFloat = 0

func image(_ name: String) -> UIImage {
let image = UIImage(named: name)!
let width = image.size.width
let height = image.size.height

DispatchQueue.main.async {
if width > height {
// Landscape image
// Use screen width if < than image width
self.width = width > UIScreen.main.bounds.width ? UIScreen.main.bounds.width : width
// Scale height
self.height = self.width/width * height
} else {
// Portrait
// Use 600 if image height > 600
self.height = height > 600 ? 600 : height
// Scale width
self.width = self.height/height * width
}
}
return image
}

Usage:

    GeometryReader { geometry in
Image(uiImage: image("image1"))
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
.overlay(
Rectangle()
.foregroundColor(.clear)
.background(LinearGradient(gradient: Gradient(colors: [.clear, .white]), startPoint: .center, endPoint: .bottom))
)
.offset(y: geometry.frame(in: .global).minY > 0 ? -geometry.frame(in: .global).minY : 0)

edit: Added the DispatchQueue.main.async block as a quick fix for 'Modifying state during view update' warning. Works but probably not the absolute best way to go about it. Might be better to put the image into it's own @State and set it in the view's onAppear method.

edit 2: Moved the image into it's own @State var which I believe is a better solution as it will make the view more reusable as you can pass an image instead of hard coding the name of the image in the view.

    @State var image: UIImage {
didSet {
let width = image.size.width
let height = image.size.height
DispatchQueue.main.async {
if width > height {
// Landscape image
self.width = width > UIScreen.main.bounds.width ? UIScreen.main.bounds.width : width
self.height = self.width/width * height
} else {

self.height = height > 600 ? 600 : height
self.width = self.height/height * width
}
}
}
}

Usage:

    GeometryReader { geometry in
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
.overlay(
Rectangle()
.foregroundColor(.clear)
.background(LinearGradient(gradient: Gradient(colors: [.clear, .white]), startPoint: .center, endPoint: .bottom))
)
.offset(y: geometry.frame(in: .global).minY > 0 ? -geometry.frame(in: .global).minY : 0)

Will have to update how the ContentView is declared by passing in a UIImage:

ContentView(image: UIImage(named: "image0")!)

How to properly fit a filled Image in its bounds on SwiftUI?

Just add .contentShape(Rectangle()) at the bottom:

            Image(uiImage: image.image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(
maxWidth: width,
maxHeight: height
)
.clipped()
.contentShape(Rectangle()) // <- Here!

Update SwiftUI View size to match image

Figured out how to do it. There were several problems with my original code. First, the ItemCells used in the ScrollView should be modified with the .fixedSize() view modifier, like so:

ScrollView(...) {
HStack(...) {
ForEach(...) { ...
ItemCell()
.fixedSize()
}
}
}

Then, changing the frame of the CustomImageCell to be use idealHeight instead of maxHeight and making the Group a VStack with a Spacer() to push everything to the bottom, as @Paulw11 had suggested in comments:

struct ItemCell: View {
var body: some View {
VStack {
Spacer()
CustomImageView(from: imageURL, placeholder: PlaceholderView(), config: { $0.resizable() })
.aspectRatio(contentMode: .fit)
.frame(maxWidth: 150, idealHeight: 190)
}

}
}

These changes fix both the image resizing animation issue and the extra space issue.



Related Topics



Leave a reply



Submit