如何为UIImageView设置圆角以适应纵横比模式

27

我通常使用以下代码设置圆角。

imageView.layer.cornerRadius = 10

当imageView设置为Aspect Fill时,它起作用。

但是当imageView设置为Aspect Fit模式,并且imageView和图片之间的比例不同时,圆角效果将无法实现。

输入图片描述

背景颜色设置为绿色以显示圆角。

是否有办法将“真实图像部分”设置为圆角。

提前感谢您的答复。


1
请参考此链接:https://dev59.com/PIvda4cB1Zd3GeqPeM7m#30747684 - Mayank Patel
或者调整图像视图的大小以适应。 - Wain
9个回答

48

使用此扩展来操作 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
        }
    }
}

没有调用这个函数

调用这个扩展方法之后


嗨,这怎么在CollectionViewCell中工作?绑定每次都返回空值... - Shaun Barney
我有一个问题,我真的想在UICollectionView cell上使用你创建的功能 @Arun Ammannaya,但是我无论如何都无法使其工作... https://stackoverflow.com/questions/50896345/how-to-get-the-frame-size-of-a-uiimageview-in-a-uicollectionview-cell - Shaun Barney
漂亮的扩展! - Linus
看起来非常慢,也许由于iOS更新了相关的方式,因为这是发布很久以前的答案。 - user5306470

5

这里是有用的、被接受的答案的Swift 3版本!

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
        }
    }
}

3
尝试以下方法可能会有所帮助:
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
    }

}

2

以下是将被接受的答案转换为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

我是objective c的新手。请问您能告诉我如何将其放入UIImageView的类别中吗?还请说明如何在图像上使用该方法。 - TheTravloper

1

首先需要将宽度和高度设置为相同的值。然后像这样设置图像属性:

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()

0
如果您在项目中使用了SDWebImage,则可以执行以下操作: myUIImageView.image = myUIImage.sd_roundedCornerImage(withRadius: 24, corners: .allCorners, borderWidth: 0, borderColor: nil)

0
我想评论Arun的答案,以帮助那些在使用Arun的方法时遇到问题的人,但在集合视图中,您必须将imageView的框架初始化为集合视图单元格的框架。
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifier", for: indexPath) as UICollectionViewCell
let imageView = UIImageView(frame: cell.frame)

显然你想要重构那个东西,但是你懂的。


0

这里有一个使用推荐的渲染器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
    }
}

然后你可以这么做:

let imageView = UIImageView(image: <your image>)
imageView. setRoundedCorners(radius: 16)

-3

将图像视图圆形化非常简单:

self.profileImageView?.clipsToBounds = true
self.profileImageView!.layer.cornerRadius = 10
self.profileImageView?.layer.borderWidth = 1.0
self.profileImageView?.contentMode = .ScaleAspectFit

但是,如果要使图像视图具有圆角和图像比例,我认为您必须将图像视图设置为ScaleAspectFill模式。


他的问题是:“如何在纵横比适应模式下设置带有圆角的UIImageView”,他并不是在询问如何缩放图像。 - iTarek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接