82

I have a UIImageView on each of my UITableView cells, that display a remote image (using SDWebImage). I've done some QuartzCore layer styling to the image view, as such:

UIImageView *itemImageView = (UIImageView *)[cell viewWithTag:100];
    itemImageView.layer.borderWidth = 1.0f;
    itemImageView.layer.borderColor = [UIColor concreteColor].CGColor;
    itemImageView.layer.masksToBounds = NO;
    itemImageView.clipsToBounds = YES;

So now I have a 50x50 square with a faint grey border, but I'd like to make it circular instead of squared. The app Hemoglobe uses circular images in table views, and that's the effect I'd like to achieve. However, I don't want to use cornerRadius, as that degrades my scrolling FPS.

Here's Hemoglobe showing circular UIImageViews:

enter image description here

Is there any way to get this effect? Thanks.

swiftcode
  • 3,039
  • 9
  • 39
  • 64

14 Answers14

142

Simply set the cornerRadius to half of the width or height (assuming your object's view is square).

For example, if your object's view's width and height are both 50:

itemImageView.layer.cornerRadius = 25;

Update - As user atulkhatri points out, it won't work if you don't add:

itemImageView.layer.masksToBounds = YES;
kanstraktar
  • 5,357
  • 2
  • 21
  • 29
tagabek
  • 1,956
  • 4
  • 16
  • 22
  • 30
    Why could this be the best answer? Well, I don't think so. Using cornerRadius causes a bad performance in scroll view, especially in iPhone4 devices. – Danny Xu Dec 30 '13 at 03:59
  • 11
    I liked the point 'set the cornerRadius to half of the width or height ' but just dont forget to add 'itemImageView.layer.masksToBounds = YES;' or else it won't work. – atulkhatri Jan 02 '14 at 13:25
  • By the way as Danny Xu commented, it will decrease the tableview scrolling performance, So should be avoided in tableview cells. – atulkhatri Jan 02 '14 at 13:28
  • 4
    this should fix your tableview scrolling performance issue. self.imageView.layer.shouldRasterize = YES; self.imageView.layer.rasterizationScale = [UIScreen mainScreen].scale; – hishboy Jun 13 '14 at 05:30
  • For Swift3: itemImageView.layer.masksToBounds = true; – Loïs Talagrand May 29 '17 at 22:03
  • Instead of static value we should give dynamic value like `self.ImageView.layer.cornerRadius = self.ImageView.frame.size.width / 2;` – Mihir Oza Jul 22 '19 at 07:56
38

To Add border

self.ImageView.layer.borderWidth = 3.0f;

self.ImageView.layer.borderColor = [UIColor whiteColor].CGColor;

For Circular Shape

self.ImageView.layer.cornerRadius = self.ImageView.frame.size.width / 2;
self.ImageView.clipsToBounds = YES;

Refer this link

http://www.appcoda.com/ios-programming-circular-image-calayer/

yazh
  • 701
  • 10
  • 15
14

Use this code.. This will be helpful..

    UIImage* image = ...;
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
    // Add a clip before drawing anything, in the shape of an rounded rect
    [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                                cornerRadius:50.0] addClip];
    // Draw your image
    [image drawInRect:imageView.bounds];

    // Get the image, here setting the UIImageView image
    imageView.image = UIGraphicsGetImageFromCurrentImageContext();

    // Lets forget about that we were drawing
    UIGraphicsEndImageContext();

It works fine for me. :)

shivam
  • 1,148
  • 1
  • 12
  • 28
10

Here is a more up to date method in swift using IBDesignable and IBInspectable to subclass UIImageView

@IBDesignable class RoundableUIImageView: UIImageView {
    private var _round = false
    @IBInspectable var round: Bool {
        set {
            _round = newValue
            makeRound()
        }
        get {
            return self._round
        }
    }
    override internal var frame: CGRect {
        set {
            super.frame = newValue
            makeRound()
        }
        get {
            return super.frame
        }

    }

    private func makeRound() {
        if self.round == true {
            self.clipsToBounds = true
            self.layer.cornerRadius = (self.frame.width + self.frame.height) / 4
        } else {
            self.layer.cornerRadius = 0
        }
    }

    override func layoutSubviews() {
            makeRound()
    }
}
Herbert Poul
  • 4,512
  • 2
  • 31
  • 48
Antzi
  • 12,831
  • 7
  • 48
  • 74
  • I had to add the following code to make it work for me (inside a table view cell): override func layoutSubviews() { makeRound() } – Herbert Poul Oct 11 '16 at 12:15
  • 1
    + 1 for @herbert. It totally worked for me when I override layoutSubviews inside the class, you should update the the code – Abdoelrhman Oct 18 '16 at 23:40
  • Thank you!! I finally did this (subclass, but in Objective-C) to handle some circular UIImageViews that just would not STAY ROUND. – John Stewart Dec 29 '17 at 17:52
7

Yes, it is possible to give layer.cornerRadius (need to add #import <QuartzCore/QuartzCore.h>)
for create circular any control but in your case instead of set layer of UIImageView it is The Best Way to Create Your Image as circular and add it on UIImageView Which have backGroundColor is ClearColor.

Also refer this Two Source of code.

https://www.cocoacontrols.com/controls/circleview

and

https://www.cocoacontrols.com/controls/mhlazytableimages

This might be helpful in your case:

iPatel
  • 46,010
  • 16
  • 115
  • 137
  • 4
    Finally, I think @iPatel is the only one who cares about the performance here. Be careful with cornerRadius if you want high performance while scroll. – Danny Xu Dec 30 '13 at 04:06
  • I'm a little confused...why did you post the circle view project link? That has nothing to do with the question, nor the answer you gave. – user717452 Jan 11 '14 at 19:35
  • @iPatel - update: the second link has been deprecated by the author and can no longer be downloaded. – trdavidson Mar 12 '15 at 23:40
3

Set the height & width of the of the UIImageView to be the same e.g.:Height=60 & Width = 60, then the cornerRadius should be exactly the half.I have kept it 30 in my case.It worked for me.

 self.imageView.layer.cornerRadius = 30;
 self.imageView.layer.borderWidth = 3;
 self.imageView.layer.borderColor = [UIColor whiteColor].CGColor;
 self.imageView.layer.masksToBounds = YES;
daisy
  • 22,498
  • 29
  • 129
  • 265
2

Usable solution in Swift using extension:

extension UIView{
  func circleMe(){
      let radius = CGRectGetWidth(self.bounds) / 2
      self.layer.cornerRadius = radius
      self.layer.masksToBounds = true
  }
}

Usage:

self.venueImageView.circleMe()
Hossam Ghareeb
  • 7,063
  • 3
  • 53
  • 64
  • Wouldn't it be better to apply the extension to `UIImageView`? This code works, but it makes the extension generic to any `UIView` objects. – swiftcode May 03 '16 at 14:22
  • `UIImageView` is already extending from `UIView`. In some cases you may need to circle some `UIViews`, so this method will work for all. – Hossam Ghareeb May 03 '16 at 14:24
2

If use some autolayout and different cells heights, u better do it this way:

   override func layoutSubviews() {
        super.layoutSubviews()
        logo.layer.cornerRadius = logo.frame.size.height / 2;
        logo.clipsToBounds      = true;
    }
Zaporozhchenko Oleksandr
  • 4,660
  • 3
  • 26
  • 48
1

I use a Round Image View class… So I just use it instead of UIImageView, and have nothing to tweak…

This class also draws an optional border around the circle. There is often a border around rounded pictures.

It is not a UIImageView subclass because UIImageView has its own rendering mechanism, and does not call the drawRect method..

Interface :

#import <UIKit/UIKit.h>

@interface MFRoundImageView : UIView

@property(nonatomic,strong) UIImage* image;

@property(nonatomic,strong) UIColor* strokeColor;
@property(nonatomic,assign) CGFloat strokeWidth;

@end

Implementation :

#import "MFRoundImageView.h"


@implementation MFRoundImageView

-(void)setImage:(UIImage *)image
{
    _image = image;
    [self setNeedsDisplay];
}

-(void)setStrokeColor:(UIColor *)strokeColor
{
    _strokeColor = strokeColor;
    [self setNeedsDisplay];
}

-(void)setStrokeWidth:(CGFloat)strokeWidth
{
    _strokeWidth = strokeWidth;
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGPathRef path = CGPathCreateWithEllipseInRect(self.bounds, NULL);
    CGContextAddPath(ctx, path);
    CGContextClip(ctx);
    [self.image drawInRect:rect];

    if ( ( _strokeWidth > 0.0f ) && _strokeColor ) {
        CGContextSetLineWidth(ctx, _strokeWidth*2); // Half border is clipped
        [_strokeColor setStroke];
        CGContextAddPath(ctx, path);
        CGContextStrokePath(ctx);
    }
    CGPathRelease(path);
}

@end
Moose
  • 2,607
  • 24
  • 23
0

Creating circular image view and thats quite easy with the below SO link, just have custom cells for your table view instead of allocating every thing in your cellForRowAtIndexPath method.

how to make button round with image background in IPhone?

The above link gives you example for buttons just use it for your image views.

Community
  • 1
  • 1
Saify
  • 190
  • 10
0

If you showing the images over a solid background color, an easy solution could be to use an overlay image with a transparent circle in the middle.

This way you can still use square images and add the circle image above them to get the circular effect.

If you don't need to manipulate your images or show them on a complex background color, this can be a simple solution with no performance hit.

Eyal
  • 10,777
  • 18
  • 78
  • 130
0

In swift, inside your viewDidLoad method, with the userImage outlet:

self.userImage.layer.borderWidth = 1;
self.userImage.layer.borderColor = UIColor.whiteColor().CGColor;
self.userImage.layer.cornerRadius = self.userImage.frame.size.width / 2;
self.userImage.clipsToBounds = true;
lifeisfoo
  • 15,478
  • 6
  • 74
  • 115
0

In Swift use this Extension for CircularImageView or RoundedImageView :

extension UIView {

    func circular(borderWidth: CGFloat = 0, borderColor: UIColor = UIColor.whiteColor()) {
        let radius = CGRectGetWidth(self.bounds) / 2
        self.layer.cornerRadius = radius
        self.layer.masksToBounds = true

        self.layer.borderWidth = borderWidth
        self.layer.borderColor = borderColor.CGColor
    }

    func roundedCorner(borderWidth: CGFloat = 0, borderColor: UIColor = UIColor.whiteColor()) {
        let radius = CGRectGetWidth(self.bounds) / 2
        self.layer.cornerRadius = radius / 5
        self.layer.masksToBounds = true

        self.layer.borderWidth = borderWidth
        self.layer.borderColor = borderColor.CGColor
    }

}

Usage:

self.ImageView.circular()
self.ImageView.roundedCorner()
Aqib Mumtaz
  • 4,936
  • 1
  • 36
  • 33
0

For circular imageview, use the below code.

self.imageView.layer.cornerRadius = self.imageView.frame.size.width / 2;
self.imageView.clipsToBounds = true

Don't forget to change the cornerRadius in viewDidLayoutSubviews method of your UIView.

Example:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.imageView.layer.cornerRadius = self.imageView.frame.size.width / 2;
    self.imageView.clipsToBounds = true
}
bharathi kumar
  • 210
  • 2
  • 8