Reputation: 263
I usually use the following code to set rounded corners.
imageView.layer.cornerRadius = 10
It works when the imageView is set at Aspect Fill.
But when the imageView is set to Aspect Fit mode, and the ratio between imageView and picture are different. The rounded corners effect won't be able to tell.
The background color is set to green for showing the rounded corners.
Is there any way to set 'real image part' to rounded corners.
Thank you in advance for your answers.
Upvotes: 26
Views: 17492
Reputation: 2198
Here a solution using the recommended renderer UIGraphicsImageRenderer
:
extension UIImageView {
func setRoundedCorners(radius: CGFloat) {
guard let image = self.image else {
fatalError("Set image first")
}
let imageLayer = CALayer()
imageLayer.frame = CGRectMake(0, 0, image.size.width, image.size.height)
imageLayer.contents = image.cgImage
imageLayer.masksToBounds = true
imageLayer.cornerRadius = radius
let renderer = UIGraphicsImageRenderer(
bounds: CGRectMake(0, 0, image.size.width, image.size.height),
format: UIGraphicsImageRendererFormat(for: traitCollection)
)
let roundedImage = renderer.image { action in
imageLayer.render(in: action.cgContext)
}
self.image = roundedImage
}
}
Then you can just do:
let imageView = UIImageView(image: <your image>)
imageView. setRoundedCorners(radius: 16)
Upvotes: 0
Reputation: 461
If you use SDWebImage
in your project, you can do the following:
myUIImageView.image = myUIImage.sd_roundedCornerImage(withRadius: 24, corners: .allCorners, borderWidth: 0, borderColor: nil)
Upvotes: 0
Reputation: 31
I wanted to comment on Arun's answer to help those who are having issues with doing Arun's method but in Collection View, you have to initiate the imageView's frame as the collection view cell's frame.
i.e.
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifier", for: indexPath) as UICollectionViewCell
let imageView = UIImageView(frame: cell.frame)
obviously you want to refactor that and stuff but you get the idea.
Upvotes: 0
Reputation: 801
This is the accepted answer converted to Objective-C:
@implementation UIImageView(Utils)
- (void)roundCornersForAspectFitWithRadius:(CGFloat)cornerRadius {
if (self.image) {
double boundsScale = self.bounds.size.width / self.bounds.size.height;
double imageScale = self.image.size.width / self.image.size.height;
CGRect drawingRect = self.bounds;
if (boundsScale > imageScale) {
drawingRect.size.width = drawingRect.size.height * imageScale;
drawingRect.origin.x = (self.bounds.size.width - drawingRect.size.width) / 2;
}
else {
drawingRect.size.height = drawingRect.size.width / imageScale;
drawingRect.origin.y = (self.bounds.size.height - drawingRect.size.height) / 2;
}
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:drawingRect cornerRadius:cornerRadius];
CAShapeLayer *mask = [CAShapeLayer new];
[mask setPath:path.CGPath];
[self.layer setMask:mask];
}
}
@end
Upvotes: 2
Reputation: 1377
This is very simple to round the image view like this:
self.profileImageView?.clipsToBounds = true
self.profileImageView!.layer.cornerRadius = 10
self.profileImageView?.layer.borderWidth = 1.0
self.profileImageView?.contentMode = .ScaleAspectFit
But for making image view rounded with image ratio, I think you have to set image view for ScaleAspectFill mode.
Upvotes: -3
Reputation: 4825
Use this extension to UIImageView:
extension UIImageView
{
func roundCornersForAspectFit(radius: CGFloat)
{
if let image = self.image {
//calculate drawingRect
let boundsScale = self.bounds.size.width / self.bounds.size.height
let imageScale = image.size.width / image.size.height
var drawingRect: CGRect = self.bounds
if boundsScale > imageScale {
drawingRect.size.width = drawingRect.size.height * imageScale
drawingRect.origin.x = (self.bounds.size.width - drawingRect.size.width) / 2
} else {
drawingRect.size.height = drawingRect.size.width / imageScale
drawingRect.origin.y = (self.bounds.size.height - drawingRect.size.height) / 2
}
let path = UIBezierPath(roundedRect: drawingRect, cornerRadius: radius)
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
}
Upvotes: 48
Reputation: 2072
Swift 3 version of the helpful, accepted answer is over here!
extension UIImageView {
func roundCornersForAspectFit(radius: CGFloat)
{
if let image = self.image {
//calculate drawingRect
let boundsScale = self.bounds.size.width / self.bounds.size.height
let imageScale = image.size.width / image.size.height
var drawingRect : CGRect = self.bounds
if boundsScale > imageScale {
drawingRect.size.width = drawingRect.size.height * imageScale
drawingRect.origin.x = (self.bounds.size.width - drawingRect.size.width) / 2
}else {
drawingRect.size.height = drawingRect.size.width / imageScale
drawingRect.origin.y = (self.bounds.size.height - drawingRect.size.height) / 2
}
let path = UIBezierPath(roundedRect: drawingRect, cornerRadius: radius)
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
}
Upvotes: 5
Reputation: 149
You first need to set the width and height to the same value. Then set the image properties like so:
imgProfile_Pic.layer.cornerRadius = cell.imgProfile_Pic.frame.size.height / 2
imgProfile_Pic.layer.borderWidth = 3.0
imgProfile_Pic.layer.borderColor = UIColor.white.cgColor
imgProfile_Pic.clipsToBounds = true
imgProfile_Pic.layoutIfNeeded()
Upvotes: 1
Reputation: 14504
Try this may help you:
import UIKit
class ViewController: UIViewController{
@IBOutlet weak var myImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myImageView.contentMode = UIViewContentMode.ScaleAspectFit
myImageView.clipsToBounds = true
//myImageView.layer.cornerRadius = 10.0
myImageView.layer.masksToBounds = true
let simpleImage = UIImage(named:"ipad5_einladung.jpg")
let corneredImage = generateRoundCornerImage(simpleImage!, radius: 10)
//Set cornered Image
myImageView.image = corneredImage;
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func generateRoundCornerImage(image : UIImage , radius : CGFloat) -> UIImage {
let imageLayer = CALayer()
imageLayer.frame = CGRectMake(0, 0, image.size.width, image.size.height)
imageLayer.contents = image.CGImage
imageLayer.masksToBounds = true
imageLayer.cornerRadius = radius
UIGraphicsBeginImageContext(image.size)
imageLayer.renderInContext(UIGraphicsGetCurrentContext())
let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundedImage
}
}
Upvotes: 3