10

I'm simply trying to create a perfectly round image. Here's my swift code:

myImage.layer.cornerRadius = myImage.frame.size.width/2
myImage.layer.masksToBounds = true

This works on a 4s, but is not quite round on a 5s, and appears as a rounded rectangle on a iphone 6.

I'm assuming this has to do with frame.size.width returning values in pixels not points or something like that, but I've been unable to solve this problem.

nwales
  • 3,521
  • 2
  • 25
  • 47
  • 1
    Where are you putting this code? I'm wondering if perhaps it's an auto layout issue and the image is stretching after you've set its corner radius appropriately... If it's in `viewDidLoad` for example, try moving it to `viewDidLayoutSubviews` – Lyndsey Scott Dec 16 '14 at 16:49

5 Answers5

23

If you're putting that code in viewDidLoad, try moving it to viewDidLayoutSubviews.

I'm guessing it's an auto layout issue -- although you've used the corner radius property appropriately and are in fact making the image frame circular, after auto-layout, the corner radius stays the same, but the image stretches so that it's no longer circular.

Lyndsey Scott
  • 37,080
  • 10
  • 92
  • 128
  • how do I show rounded UIImage in UICollection view.I am loading images in cellForItemAtIndexPath function of collectionView from api. – Dashrath Jan 22 '16 at 12:41
  • 1
    @Dashrath Call yourCell.layoutIfNeeded() before setting the layer's properties. – Lyndsey Scott Jan 24 '16 at 08:32
  • I added cell.itemThumb.layer.cornerRadius = cell.itemThumb.frame.size.height/2; cell.itemThumb.clipsToBounds = true;cell.itemThumb.layoutIfNeeded(); but still image shows rounded ractangle. am i missing something again ? – Dashrath Jan 25 '16 at 09:53
  • 2
    @Dashrath Set layoutIfNeeded **before** setting the layer's properties. – Lyndsey Scott Jan 25 '16 at 12:55
  • 1
    @Dashrath you are my hero! been trying to figure this out forever, thought the issue was with the collectionViewLayout and was trying invalidateLayout to no avail – MadeByDouglas Jan 27 '16 at 00:59
  • cell.layoutIfNeeded() cell.companyLogoImageView.clipsToBounds = true cell.companyLogoImageView.layer.cornerRadius = cell.companyLogoImageView.frame.height / 2 @Lyndsey Scott I am calling layoutIfNeeded() before setting the layer properties as mentioned, but I dont get the desired rounded corners when the tableView loads. However, as i scroll the tableView, the rounded corners appear correctly. What might be causing this? – Sujal Sep 12 '18 at 06:40
3

If your code is in viewDidLoad in ViewController, try moving it to viewDidLayoutSubviews.

If your rounded imageView is in tableViewCell, try moving it to draw.

override func draw(_ rect: CGRect) {
    avatarView.layer.cornerRadius = avatarView.frame.size.width / 2
    avatarView.layer.masksToBounds = true
    avatarView.clipsToBounds = true
    avatarView.contentMode = .scaleAspectFill
}
Phillip
  • 801
  • 10
  • 13
2

The problem is that if you change the cornerRadius of Any view, and expect it to look like a circle, the view has to be a square.

Now, because of different devices and different device size, the size of your image view might change and it may be a rectangle.

For e.g. If you view is a 50 * 50

myImage.layer.cornerRadius = myImage.frame.size.width/2

This would add corner radios of 25 on both sides to make it a circle.

But because of auto layout of device change, your view might be a 50 * 80

Corner radius would add a 25, but as the height is 80, it will add 25 on both sides, and the remaining 30 won't be a curve and look straight.

What you can do is try viewing the screen in various orientations in the storyboard and change auto layout Constraints (Or structs and springs) to ensure that the image view is a square in all the devices

Kakshil Shah
  • 3,466
  • 1
  • 17
  • 31
1
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

  myImage.layer.cornerRadius  = myImage.frame.size.width/2
  myImage.layer.masksToBounds = true
}
0

This should work:

myImage.layer.cornerRadius = myImage.**bounds**.size.width/2
myImage.layer.masksToBounds = true
Lance Roberts
  • 22,383
  • 32
  • 112
  • 130