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

I have to fix a problem with Images on SwiftUI. I currently have to fill the images I receive in a certain vertical container, which are the cells of a LazyVGrid, but the problem is that the tappable area expands over the designated one.
I used the Accessibility Inspector, and I found out that the area in excess is due the Images. (screenshot attached)
The code I'm using is something similar to the following:
Image(uiImage: image.image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(
maxWidth: width,
maxHeight: height
)
.clipped()
I thought that by having the frames and the clipped method I could get rid of this problem, but that's not the case unless I'm using some squared images. Any idea of what could work to fix this problem? Thanks!

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

Wrap content in Geometry Reader and you need to know the aspect ratio like I set 720/460 below
GeometryReader { gr in
Image(uiImage: image.image)
.resizable()
.aspectRatio(720/460, contentMode: .fit)
}
.clipped()
.aspectRatio(720/460, contentMode: .fit)

Related

How to indent first line of Label in SwiftUI?

I simply need to achieve something like this:
using:
ZStack {
Image.book
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 12, height: 10)
Text(verbatim: entry.verse)
.font(.openSansRegular(withSize: 11))
}
But have no idea how to achieve it.
Similar question but for UILabel was here

Can't use rotation effect in clip shape in swiftUI

This i my code:
Image()
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.clipShape(Rectangle().cornerRadius(8).rotationEffect(.degrees(45)))
I receive this error:
Instance method 'clipShape(_:style:)' requires that 'some View' conform to 'Shape'
Or you know another way to crop my image to diamond?
Like this?
You can encapsulate the image in a ZStack and rotate them opposite to each other. Then set the frame of the ZStack to match the image. Feel free to ask if anything is unclear!
ZStack {
Image("IMG_1544")
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.rotationEffect(.degrees(-45))
}
.frame(width: cos(.pi/4) * 200, height: sin(.pi/4) * 200)
.cornerRadius(8)
.rotationEffect(.degrees(45))
Try to use mask instead, maybe it will be enough for your needs, and it accepts views, like
Image()
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.mask(Rectangle().cornerRadius(8).rotationEffect(.degrees(45))) // << here !!

SwiftUI: How to know correct order of modifiers?

I'm pretty new to SwiftUI, learning it for the first time, and couldn’t understand why the below snippet doesn’t work. Ideally, the VStack should stretch in all directions and the Image should have a width of 200px without losing its aspect ratio.
Code
struct ContentView: View {
var body: some View {
VStack() {
Image("Image Name")
.resizable()
.frame(width: 200)
.aspectRatio(contentMode: .fit)
}
.background(Color.red)
.frame(maxWidth: .infinity,maxHeight: .infinity)
}
}
After I accidentally reordered the modifiers, it worked. So, how am I supposed to know the correct order of modifiers without a hit and trial method each time?
// new VStack modifier order
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.red)
// new Image modifier order
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 200)
The best way to think about it for now is to imagine that SwiftUI renders your view after every single modifier. So, as soon as you say .background(Color.red) it colors the background in red, regardless of what frame you give it. If you then later expand the frame, it won’t magically redraw the background – that was already applied.
Of course, this isn’t actually how SwiftUI works, because if it did it would be a performance nightmare, but it’s a neat mental shortcut to use while you’re learning.
Please refer to this link for more details https://www.hackingwithswift.com/books/ios-swiftui/why-modifier-order-matters#:~:text=Every%20time%20we%20modify%20a,up%3A%20ModifiedContent%3CModifiedContent%3C%E2%80%A6

SwiftUI - How to apply aspectFit to image so it does not go outside of designated area

I am trying to fit a square shaped image in rectangle shaped ImageView. With storyboard, I can easily do it with content mode .aspectFit but I am unable to figure out how to do it with SwiftUI.
I am currently doing something like this:
Image("BG")
.resizable()
.aspectRatio(contentMode: .fill)
.scaledToFill()
.clipped()
.frame(height: 200)
which gives below output, notice the blue border is my actual ImageView:
However, I am expecting something like this which I did in storyboard:
You need to clip it after set size, like
Image("BG")
.resizable()
.aspectRatio(contentMode: .fill)
.scaledToFill()
.frame(height: 200)
.clipped() // << here !!

SwiftUI edges become visible after scaling images to fill

I am new to swiftUI and I have been trying to place images in a Rounded rectangle but every time I use scaledToFill() The corners of the rectangle disappear.
This is my code :
Image("img_6").resizable()
.scaledToFill()
.clipShape(RoundedRectangle(cornerRadius: 55,
style: .continuous))
.shadow(radius: 9)
.frame(height: 550).clipped()
Modifiers order is important. In your case just move .clipShape after .frame, as
tall:
wide:
Color.clear
.frame(height: 550)
.overlay(Image("img")
.resizable()
.scaledToFill())
.clipShape(RoundedRectangle(cornerRadius: 55,
style: .continuous))
.shadow(radius: 9)
Note: .clipped not needed, because .clipShape already performs clipping

Resources