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")!)
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
Swiftui getting an image's displaying dimensions
I would use GeometryReader
on background so it reads exactly size of image, as below
@State var imageSize: CGSize = .zero // << or initial from NSImage
...
Image(nsImage: self.img!)
.resizable()
.scaledToFit()
.background(rectReader())
// ... somewhere below
private func rectReader() -> some View {
return GeometryReader { (geometry) -> Color in
let imageSize = geometry.size
DispatchQueue.main.async {
print(">> \(imageSize)") // use image actual size in your calculations
self.imageSize = imageSize
}
return .clear
}
}
How to set the height of the PageTabView
Use .frame(height: yourDesiredHeight)
. However this will keep your image scaled as if you're using .scaleToFit()
which will try to fit all of the image in the frame.
Try using .aspectRatio(contentMode: .fill)
to fill the whole frame.
How Do I get uniform view size when using Image and SFSymbols in SwiftUI?
If you want to normalize the sizes, you could use a PreferenceKey
to measure the largest size and make sure that all of the other sizes expand to that:
struct ContentView: View {
let symbols = [ "camera", "comb", "diamond", "checkmark.square"]
@State private var itemSize = CGSize.zero
var body: some View {
HStack(spacing: 0) {
ForEach(Array(symbols), id: \.self) { item in
VStack {
Image(systemName: item).font(.largeTitle)
}
.padding()
.background(GeometryReader {
Color.clear.preference(key: ItemSize.self,
value: $0.frame(in: .local).size)
})
.frame(width: itemSize.width, height: itemSize.height)
.border(.red)
}.onPreferenceChange(ItemSize.self) {
itemSize = $0
}
}
.border(Color.black)
}
}
struct ItemSize: PreferenceKey {
static var defaultValue: CGSize { .zero }
static func reduce(value: inout Value, nextValue: () -> Value) {
let next = nextValue()
value = CGSize(width: max(value.width,next.width),
height: max(value.height,next.height))
}
}
Adjust Image Size of Image to Parent View Size
If I understood correctly the intention was to fill proportionally, so
ZStack{
Image(backgoundImage!)
.resizable() // for resizing
.scaledToFill() // << here !! // for filling image on ImageView
but in that case it can spread out of bounds, so it needs to be clipped in place of .frame
applied, so either
ImageCard("image")
.frame(decide the size of the image)
.clipped() // << here !!
or, better, as already described inject dimension inside card and apply it there, like
Image(backgoundImage!)
.resizable() // for resizing
.scaledToFill() // << here !!
.frame(decide the size of the image)
.clipped() // << here !!
.cornerRadius(5)
.shadow(color: .gray, radius: 6, x: 0, y: 3)
}
How to set width and height of an image in SwiftUI?
Try this
Image("testImg")
.resizable()
.frame(width: 50.0, height: 50.0)
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)
Related Topics
Format Println Output in a Table
Swiftui Multiline Text Background Color
Distributednotificationcenter - How to Pass Data Between Applications
Swift Vscode Class in Other File Not Recognized
Call Function When If Value in Nsuserdefaults.Standarduserdefaults() Changes
How to Make a Function Complete Before Calling Others in an Ibaction
Avcapturevideopreviewlayer Is Not Visible on The Screenshot
Corebluetooth on MAC Command Line Application
Using Nil-Coalescing Operator with Try? for Function That Throws and Returns Optional
Swiftui - Unwrap Optional Image Data to Create Image Based on Uiimage(Data)
Are Built-In Intrinsic Functions Available in Swift 3
Can't Create Default Closure Parameter in Array Extension Method in Swift
Passing Dynamic Int Variable from One Class to Another Class in Swift
Write into Settings Bundle in Swift
Custom Uitabbar Unselected Item's Color
Swift Protocol as Generic Parameter