I have a very simple collection view that has images in it, my Cell class looks like this:
class ImageListCell: UICollectionViewCell {
@IBOutlet weak var btnDelete: UIButton! {
didSet {
btnDelete.layer.cornerRadius = btnDelete.frame.height / 2
}
}
@IBOutlet weak var imageView: UIImageView!
@IBAction func btnDeleteTap(_ sender: Any) {
print("Delete image")
}
}
The cell's imageView constraints have some padding at the top and trailing edge:
If I color the ImageListCell background red and the imageView background green, this is what it looks like:
Which is 100% correct!
However, if all I do is add an image to imageView the contraints get all goofy?
This only happens in .aspectFit, if I change it to .aspectFill it works but the images are all stretched.
I made sure I'm not adjusting cell size or anything and Estimated Size
on the collection view is turned off.
Does anyone have any idea why .aspectFill is overriding my constraints?
CodePudding user response:
Nothing is happening to your constraints. The image view is exactly where you put it.
In the first picture-with-the-image,
.aspectFit
is behaving exactly as expected: no empty space is left within the image view around the outside of the image, and the image is not distorted. If you don't like the fact that the image is "leaking" off the right side, that's merely because you forgot to set your image view'sclipsToBounds
totrue
.The second picture-with-the-image is not
.aspectFill
as you claim. It is.scaleToFill
. There is a huge difference. So your statement of the phenomena is not even correct..scaleToFill
can distort the image;.aspectFill
would not do that (but it would display the green background of the image view).
CodePudding user response:
There are a few things in your question that seem incorrect.
You are referring to content modes with values such as .aspectFit
and .aspectFill
. In Swift code there are no such values. These would be .scaleAspectFit
and .scaleAspectFill
. In a storyboard the "Content Mode" property of a view can be things like "Aspect Fit", "Aspect Fill", and others.
Since you setup your cell in a storyboard I'll refer to the storyboard property settings. Everything I describe applies to the UIImageView outlet in your collection view cell.
The first screenshot you show with what you claim to be as .aspectFit
would only happen if you set the "Content Mode" to "Aspect Fill" (not "Aspect Fit" as you claim) and you turned off the "Clips to Bounds" setting. With "Aspect Fill" set, a wide image will correctly fill the height of the image view (which is why you still see the top red border, but the left and right sides of the image would overflow outside the image view (which is why you can't see the right red border). If "Clip to Bounds" was checked, the right red border would be visible. The collection view cell itself clips all of its content which prevents the overflowing image from spilling out of the cell's frame.
The second screenshot you show with what you claim to be as .aspectFill
would be the result of setting "Content Mode" to "Scale To Fill", not "Aspect Fill". The result would be the same whether "Clip to Bounds" was checked or not. "Scale to Fill" distorts the image as needed to fully fill the height and width of the image view.
Based on your description you want to set "Content Mode" to "Aspect Fit". While not really needed for "Aspect Fit", it wouldn't hurt to enable "Clip to Bounds". This will show the entire image with appropriate green borders and no distortion.
tl;dr - your constraints are fine. You are not really setting the image view's content mode to "Aspect Fit" in the first image picture. You are setting it to "Aspect Fill" and "Clip to Bounds" is off.
If you want to do this in code you want:
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true // optional for .scaleAspectFit