142

I'm at a bit of a loss. I've used the layer property of UIView to round the corners of multiple elements in my app. However, this one UIImageView is simply not complying. Not sure what I am missing.

The UIImageView (called previewImage) is contained in a Table View Cell. I've tried setting the cornerRadius property multiple location (in the cell itself and in the controller that creates the cell) to no avail.

static NSString *CellIdentifier = @"MyTableViewCell";

MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
    cell = [topLevelObjects objectAtIndex:0];
    cell.previewImage.layer.cornerRadius = 20; //Made it 20 to make sure it's obvious.
}

Is there something about the way cells are loaded that I'm missing?

Evan Mulawski
  • 54,662
  • 15
  • 117
  • 144
MarkPowell
  • 16,482
  • 7
  • 61
  • 77

13 Answers13

392

You need to set the layer's masksToBounds property to YES:

cell.previewImage.layer.masksToBounds = YES;

This is because the UIImageView control creates a pseudo-subview to hold the UIImage object.

Michael Sacks
  • 917
  • 1
  • 11
  • 17
Evan Mulawski
  • 54,662
  • 15
  • 117
  • 144
  • 21
    Unless you also rasterize the view (view.layer.shouldRasterize = YES), every frame will require a re-mask of all the pixels. – jjxtra Aug 12 '13 at 13:41
  • @jjxtra so it's better to set `shouldRasterize = false`? – user924 Apr 19 '19 at 17:54
  • 2
    If shouldRasterize is false you pay the mask creation overhead everyframe. If shouldRasterize is true and your layer changes every frame, you pay the mask overhead and the rasterization overhead. Ideal case is a static (not changing very often) layer with shouldRasterize = true. – jjxtra Apr 20 '19 at 03:53
56

Also worth noting that

  1. If you are using aspectFit AND cornerRadius with clipsToBounds/masksToBounds, you won't get the rounded corners.

i.e if you have this

theImageView.contentMode = .scaleAspectFit

and

   theImageView.layer.cornerRadius = (theImageView.frame.size.height)/2
    theImageView.clipsToBounds = true

or

theImageView.layer.masksToBounds = true

It won't work. you will have to get rid of aspectFit code

//theImageView.contentMode = .scaleAspectFit
  1. Make sure the width and the height for the Image View is same
Naishta
  • 11,885
  • 4
  • 72
  • 54
  • In short: set aspect ratio 1:1 if you want to use AspectFit – djdance Mar 11 '19 at 11:24
  • It won't work. you will have to get rid of aspectFit code This helped me – Shoaib Bagwan Jun 23 '21 at 04:45
  • If we want to use aspect-fit, we can create our own rounded-corner mask. Ref: https://stackoverflow.com/questions/34962103/how-to-set-uiimageview-with-rounded-corners-for-aspect-fit-mode – Sam Sep 21 '22 at 16:04
24

This should work

cell.previewImage.clipsToBounds = YES;

cell.previewImage.layer.cornerRadius = 20;
j0k
  • 22,600
  • 28
  • 79
  • 90
Teena nath Paul
  • 2,219
  • 23
  • 28
12

I believe you need to set:

cell.previewImage.layer.masksToBounds = YES;
cell.previewImage.layer.opaque = NO;
Daniel Dickison
  • 21,832
  • 13
  • 69
  • 89
4

In Xcode Interface Builder, selecting 'Clip Subviews' Drawing attribute for the view together with setting the corner radius in the code cell.previewImage.layer.cornerRadius = 20;does the job for me!

See 'Clip Subviews' option in IB

koira
  • 1,197
  • 8
  • 10
2

Try this below piece of code

cell.previewImage.layer.cornerRadius = 20;
cell.previewImage.clipsToBounds = YES;
Ramkumar chintala
  • 958
  • 11
  • 24
2

Try this code:-

self.imgaviewName.clipsToBounds = true
self.imageviewName.layer.cornerRadius = 10
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • Code-only answers are discouraged. Please click on [edit] and add some words summarising how your code addresses the question, or perhaps explain how your answer differs from the previous answer/answers. Thanks – Nick Dec 20 '18 at 11:34
2

For imageView.contentMode = .scaleAspectFill the cornerRadius is not applied if the image is very large, depending on the hardware.

Some tests with resized panorama images:

  • iPhone X, image size 5000x1107: 4000x886: ✅
  • iPhone 6s Plus, image size 10000x2215: 5000x1107: ✅
  • iPhone 6s, image size 10000x2215: 5000x1107: ✅

The imageView dimensions where 160x100. Interestingly, the newer hardware isn't necessarily more capable.

Feel free to edit this post with more test results!

Ortwin Gentz
  • 52,648
  • 24
  • 135
  • 213
2

UIImageView gives cornerRadius with clipsToBounds folowing is example of Swift and Objectiv-C (The followfing example code for round image)

Swift

myImageView.layer.cornerRadius = myImageView.frame.size.height/2.0
myImageView.clipsToBounds = true

Objectiv -C

[myImageView.layer setCornerRadius:myImageView.frame.size.height/2.0];
[myImageView setClipsToBounds:TRUE];
Bera Bhavin
  • 673
  • 5
  • 10
1

Swift 4.2 Answer:

In order for the corner radius to work, add the image to a UIView and then you need to set the image's masksToBounds property to true:

planeImage.layer.masksToBounds = true
planeImage.layer.cornerRadius = 20

Note: Replace 20 by the desired cornerRadius

IronmanX46
  • 558
  • 7
  • 16
1

Nothing from the previous answers is working?

It may happen that the size of the UIImageView is bigger than the image size. Corner radius can be set well but not visible in that case.

Quick check of the UIImageView size by code: (or can use "View UI Hierarchy" tool in XCode)

self.imageView.backgroundColor = [UIColor greenColor]; 

In this scenario you should assure that UIImageView has the same aspect ratio as the image.

Marek Manduch
  • 2,303
  • 1
  • 19
  • 22
  • This was my problem - setting the color showed me that it was working but my image was smaller than my image view. In my case I ended up making the background color match the background of the image so it looks rounded – devjme Feb 09 '22 at 21:30
0
-(void) viewDidAppear:(BOOL)animated{
       [super viewDidAppear:animated];
       [self setMaskTo:viewDistance 
             byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight];
           }

- (void)setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners
     {
      UIBezierPath *rounded = [UIBezierPath 
                bezierPathWithRoundedRect:view.bounds
                                              byRoundingCorners:corners

                     cornerRadii:CGSizeMake(20.0, 20.0)];

          CAShapeLayer *shape = [[CAShapeLayer alloc] init];
          shape.frame = self.view.bounds;
         [shape setPath:rounded.CGPath];
          view.layer.mask = shape;
       }
Maulik Patel
  • 2,045
  • 17
  • 24
0

You can use this code

override func viewDidLayoutSubviews() { 
    yourImageView.layer.cornerRadius = yourImageView.frame.width / 2
}
Ildar
  • 1
  • 1