Rounded corners clipped in UIImageView - ios

I am trying to round the corners on my UIImageView in tableViewCells, however, for some reason, they are clipped. I have tried this:
cell.characterThumbnail.layer.masksToBounds = true
cell.characterThumbnail.layer.cornerRadius = 15
and this is the result I get:
If I use the debug 3D viewer I get the frame is larger than I've set (I want 84 * 84 but it shows 84 * 110). Shown here:
Why are there different sizes? And why are the rounded corners clipped? I have to point out that the image in the UIImageView is downloaded from an URL for each thumbnail.
Any help on this matter is much appreciated. It has bugged me for a week lol.
P.S. I forgot to mention that I've read almost every single "rounded corner" question here on SO and elsewhere on the internet, but no mention of clipped corners. Also, I have thought about rounding the actual image before displaying it in the UIImageView, but that makes the tableView scrolling jerky.
Edit: Whole project at https://github.com/Aecasorg/WoWilvlChecker

I suspect your image views are set to 'aspectFit', not aspectFill:

You have to set clipsToBounds true and give it a desired radius.
cell.image.contentMode = .ScaleAspectFill
cell.image.layer.cornerRadius = 10
cell.image.clipsToBounds = true
//Use this to add border
cell.image.layer.borderWidth = 3
cell.image.layer.borderColor = UIColor.whiteColor().CGColor

The problem what see is that round corner is getting drawn on 84X110 and not 84X84. That's why it looks strange.
Please call sizeToFit() (this resizes and moves the receiver view so it just encloses its subviews.).
cell.characterThumbnail.sizeToFit()
cell.characterThumbnail.clipsToBound = true
just before
cell.characterThumbnail.layer.masksToBounds = true
cell.characterThumbnail.layer.cornerRadius = 15
However, if you want to keep thumbnail-view fixed 84X84 and resize the image then you need to set aspectFill.
And in the storyboard of (WoWilvlChecker) fix the width and height of the view to 84X84
Also I think cornerRadius not needed to be 15. A value like 3-5 should be sufficient.

I checked your repo.
Remove centerY constraint, it seems centerY is causing this "stretched height" problem.
If you want to make imageView's Size applied,
then set width, height, (centerX, CenterY) or (vertical one, horizontal one)

Project has problems with layout constraints and content mode in the imageView.
Just add height constraint for the imageView and change content mode to Aspect fill.
Also I recommend to use smaller corner radius, for example 5.0. You can exam my changes in the pull request.

It is all due to constraints. All I needed was to get rid of the "Leading Space to: Superview" and "Bottom View to: Superview" constraints I had set up and add an "Align Center Y to: Superview" and that sorted it. Thanks to everyone for responses and suggestions!

Related

Self-sizing tableview cell with only imageView [duplicate]

This question already has answers here:
Auto-Layout: Get UIImageView height to calculate cell height correctly
(5 answers)
Closed 4 years ago.
I'm struggling with the following problem:
I have a TableViewController in which every cell has only an imageView. It uses autolayout to cell's contentView's margins and it is set to aspectFit.
What I want is the height of cell to size accordingly to the imageView's height.
In the first screenshot you see the white spaces at each side of the first image and at the top (and also the bottom - second screenshot) of the second image.
Note: my images' aspect ratio is variable.
I've already set this with no luck:
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 300
Also this in cellForRowAt:
cell.setNeedsLayout()
cell.layoutIfNeeded()
Any advice is well received.
Thank you.
Images with aspect fill here
The constraints
You need to create these constraints , aspect ratio here is 3:1 you can change it according to yours , also the real image should have same aspect to stretch completely as you set contentMode to aspectFit
Edit:
If the aspect is variable then you need these constraints
then hook the height constraint and do this in cellForRowAt after you download / get from cache
cell.imageHeight.constant = imageRealHeight * imageCellWidth / imageRealWidth
This is due to the way the image view returns it's intrinsicContentSize. I currently believe this is a bug and should be changed. I have raised a radar for this.
When you put an image into an image view with .scaleAspectFit and with a constraint on one dimension (width or height).
Then it will scale the image down.
So if you start with an image of 300x300 and put it into an image view with a width constraint of 100 then you will get an image view that is 100 points wide.
However, the image view uses the unscaled image for the intrinsicContentSize and so it will want to be 300 points high.
This is the problem you are facing now.
The only fix for this currently is to calculate the aspect ratio of the image and manually set that as a constraint on the image view.
So you might have a line like this...
imageView.image = theImage
You can add to that to add an aspect ratio constraint...
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: image.size.height / image.size.width).isActive = true
Of course, you will also need to remove any constraints added already. Or possibly create the constraint as a property of the cell etc...

View changes size depending on device screen size, but should have a fixed size

I have created an orange circle using a UIView100 height and 100 width with a radius of 50. This was done in the 4 inch setup.
When i move up to the 4.7inch or higher the circle becomes distorted.
What do i do so that the circle doesn't get distorted when displayed on larger devices?
So I guess you used Xcode's “Reset to Suggested Constraints” option, like this:
When you do that, Xcode guesses what constraints you want. Unfortunately, in your case, it guessed wrong. It did create the centering constraints you wanted, but it did not create the width and height constraints you wanted. Instead it created leading edge and top edge constraints, like this:
So when you load your scene on a larger device, in order to satisfy those constraints, auto layout has to make the view larger, like this:
To fix this, you need to delete the edge constraints:
And add width and height constraints:
So your final constraints on the subview look like this:
With these constraints, when you load your scene on a larger device, the subview will stay centered and not change size:
I'm betting you used a fixed corner radius to make a circular UIView (which would have a constraint for 1:1 aspect ratio too). Just make it so the radius of the corners is calculated somewhere where the right dimensions for the view can be known. viewDidLayoutSubviews is a good place as it'll take care of other resizes like screen rotation.
override func viewDidLayoutSubviews() {
self.circleView.layer.cornerRadius = self.circleView.frame.size.width / 2 // Assumes width == height because of 1:1 aspect ratio constraint
}
Alternatively don't make the size of your view depend on the width or height of the screen (i.e. remove constraints to the sides, center it and give it a fixed width and height)

How to use Autolayout to achieve result as per shown screen

I'm developing an app where I'm facing an issue to achieve one UI layout only for iPhone devices. This is the layout that I'd like to achieve:
I want to achieve overlapped views that layout should be same on every device from 5s to 7 plus.
The key is setting proportional constraints.
Start with adding a UIView to hold the 4 elements - background, man, woman and heart.
Add a UIImage for the background, and pin the edges to the edges of the view - that's the easy part.
Add a UIImage for the Man...
Set the Aspect Ratio to 1:1 to keep it square (well, round in this case).
Set the Height constraint equal to the Height of the "containing" view, but then set the multiplier to less than 1 to make it relative to the view. In this case, 0.6 is pretty close.
Set constraints for Centered Horizontally and Vertically... then set the Multipliers to keep the image left and above the centers. 0.64 on horizontal, and 0.9 on vertical work pretty good.
Add a UIImage for the Woman...
Set the Height and Width constraints equal to the Man image.
Set constraints for Centered Horizontally and Vertically... then set the Multipliers to keep the image right and below the centers. 1.4 on horizontal, and 1.2 on vertical work pretty good.
Add a UIImage for the Heart...
Set the Aspect Ratio to 1:1 (or whatever gives you the proper ratio for your heart image).
Set the Height constraint equal to the Height of the "containing" view, but then set the multiplier to less than 1 to make it relative to the view. In this case, 0.15 is pretty close.
Set constraints for Centered Horizontally and Vertically... then it will need a little adjustment o note Vertical 1.05 worked for me.
Now, you just need to set appropriate constraints for the "containing" view, and all the elements will scale and position themselves within it.
When you're all done, it should (hopefully) look like this:
I put the project up in a GitHub repo for you to look at: https://github.com/DonMag/AnotherLayoutExample

Why does adding an align with centre constraint to a UIImage throw out the radius of corners setting?

I am trying to turn a square image into a circle. I am using this code to do it:
profilePicture2.layer.cornerRadius = profilePicture2.frame.size.height/2
profilePicture2.clipsToBounds = true
It works perfectly, until I try centre the image in the container view by adding a 'Align centre X to superview' constraint. When I add this constraint I simply get very rounded corners instead of a circle.
In fact, it seems to half the value of the corner radius. So if the image has a height of 100, and corner radius should be set to 50, it LOOKS like the radius value is set to 25.
No other constraints have been added to the image.
What is going on here?
You are calling this code (profilePicture2.layer.cornerRadius = profilePicture2.frame.size.height/2) before the image is being resized. You need to do it after the autolayout has finished work. The problem is that the image at the start is (for example) 100 points wide and you set the corner radius to 50 points. And after that autolayout resizes the image to (again, example) 300 points but your corner radius remains 50 points. You just need to update it after autolayout has completed.
Or if you do not want to have an image that big, make sure you put constraints on width and height and just center it the superview.

Full Screenbackground Image in Swift

I currently try to get a fullscreen background for my iOS Project this means the image should stretch over the full background.
I currently try 2 things but won't worked out as solution.
1)
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background.png")!)
This only set the background image on the actual image size and repeat it in x and y, it does not stretch the image to fullscreensize.
2)
use a UIImage and make it equal to width and height and use aspect fill, this also does not give the wanted solution and also use much memory
Is there any other way to get this done?
So you have two ways to do it always with AutoLayout
1) With an addition of an Inequality constraint like shown in the images below.
2) Or by adding Leading, Trailing space and Top, bottom space Constraint and centering vertically and horizontally constraints but NO explicit height nor width constraint.

Resources