繁体   English   中英

如何在Swift中创建圆形轮廓图像或圆角图像,边框不会泄漏?

[英]How To Create in Swift a Circular Profile Picture or Rounded Corner Image with a border which does not leak?

基于以下源代码

    @IBOutlet var myUIImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.makingRoundedImageProfileWithRoundedBorder()
    }

    private func makingRoundedImageProfileWithRoundedBorder() {    
        // Making a circular image profile.
//        self.myUIImageView.layer.cornerRadius = self.myUIImageView.frame.size.width / 2
        // Making a rounded image profile.
        self.myUIImageView.layer.cornerRadius = 20.0

        self.myUIImageView.clipsToBounds = true

        // Adding a border to the image profile
        self.myUIImageView.layer.borderWidth = 10.0
        self.myUIImageView.layer.borderColor = UIColor.whiteColor().CGColor
    }

事实上,我能够呈现圆形或圆形UIImageView,但问题是如果我们添加边框,图像会有点泄漏。 使用圆形UIImageView会更糟糕,只要边框弯曲,它就会泄漏,因此无论如何都会泄漏! 您可以在下面找到结果的屏幕截图:

UIImageView呈现

有什么方法可以解决这个问题吗? 任何回答此问题的示例代码都将受到高度赞赏。

注意:解决方案必须尽可能与iOS 7和8+兼容。

第一解决方案

基于@JesperSchläger的建议

“如果我可以建议一个快速而肮脏的解决方案:

您可以在图像视图下方添加另一个白色视图,而不是在图像视图中添加边框。 使视图在任一方向上延伸10个点,并使其角半径为20.0。 为图像视图指定角半径10.0。“

请在下面找到Swift实现:

import UIKit

class ViewController: UIViewController {

   @IBOutlet var myUIImageView: UIImageView!

   @IBOutlet var myUIViewBackground: UIView!

   override func viewDidLoad() {
        super.viewDidLoad()

        // Making a circular UIView: cornerRadius = self.myUIImageView.frame.size.width / 2
        // Making a rounded UIView: cornerRadius = 10.0
        self.roundingUIView(self.myUIImageView, cornerRadiusParam: 10)
        self.roundingUIView(self.myUIViewBackground, cornerRadiusParam: 20)
   }

   private func roundingUIView(let aView: UIView!, let cornerRadiusParam: CGFloat!) {
       aView.clipsToBounds = true
       aView.layer.cornerRadius = cornerRadiusParam
   }

}

二解决方案

将在CALayer上设置圆形蒙版。

请在下面找到第二个解决方案的Objective-C实现:

CALayer *maskedLayer = [CALayer layer];
[maskedLayer setFrame:CGRectMake(50, 50, 100, 100)];
[maskedLayer setBackgroundColor:[UIColor blackColor].CGColor];

UIBezierPath *maskingPath = [UIBezierPath bezierPath];
[maskingPath addArcWithCenter:maskedLayer.position
                       radius:40
                   startAngle:0
                     endAngle:360
                    clockwise:TRUE];

CAShapeLayer *maskingLayer = [CAShapeLayer layer];
[maskingLayer setPath:maskingPath.CGPath];

[maskedLayer setMask:maskingLayer];
[self.view.layer addSublayer:maskedLayer];

如果您从行UIBezierPath *maskingPath = [UIBezierPath bezierPath]; 通过[maskedLayer setMask:maskingLayer]; 你会看到这个图层是一个正方形。 但是,如果未对这些行进行注释,则该图层为圆形。

注意:我既没有测试第二个解决方案也没有提供Swift实现,所以请随意测试它,并通过下面的评论部分让我知道它是否有效。 也可以随意编辑这篇文章,添加第二个解决方案的Swift实现。

我致力于改进代码,但它一直在崩溃。 我会继续努力,但我似乎有一个(粗略)版本工作:

编辑更新了一个更好的版本。 我不喜欢init:coder方法,但也许可以考虑因素或改进

class RoundedImageView: UIView {
    var image: UIImage? {
        didSet {
            if let image = image {
                self.frame = CGRect(x: 0, y: 0, width: image.size.width/image.scale, height: image.size.width/image.scale)
            }
        }
    }
    var cornerRadius: CGFloat?

    private class func frameForImage(image: UIImage) -> CGRect {
        return CGRect(x: 0, y: 0, width: image.size.width/image.scale, height: image.size.width/image.scale)
    }

    override func drawRect(rect: CGRect) {
        if let image = self.image {
            image.drawInRect(rect)

            let cornerRadius = self.cornerRadius ?? rect.size.width/10
            let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
            UIColor.whiteColor().setStroke()
            path.lineWidth = cornerRadius
            path.stroke()
        }
    }
}

let image = UIImage(named: "big-teddy-bear.jpg")

let imageView = RoundedImageView()
imageView.image = image

让我知道你是否正在寻找那种东西。

一点解释:

我相信你已经发现,iOS可以应用的“边界”并不完美,并且出于某种原因显示了角落。 我找到了一些其他的解决方案,但似乎都没有。 这是UIView的子类而不是UIImageView的原因是没有为UIImageView子类调用drawRect: UIImageView 我不确定这段代码的性能,但从我的(有限的)测试看起来很好

原始代码:

class RoundedImageView: UIView {

    var image: UIImage? {
        didSet {
            if let image = image {
                self.frame = CGRect(x: 0, y: 0, width: image.size.width/image.scale, height: image.size.width/image.scale)
            }
        }
    }

    private class func frameForImage(image: UIImage) -> CGRect {
        return CGRect(x: 0, y: 0, width: image.size.width/image.scale, height: image.size.width/image.scale)
    }

    override func drawRect(rect: CGRect) {
        if let image = self.image {
            self.image?.drawInRect(rect)

            let path = UIBezierPath(roundedRect: rect, cornerRadius: 50)
            UIColor.whiteColor().setStroke()
            path.lineWidth = 10
            path.stroke()
        }
    }
}

let image = UIImage(named: "big-teddy-bear.jpg")

let imageView = RoundedImageView()
imageView.image = image
imageView.layer.cornerRadius = 50
imageView.clipsToBounds = true

如果我建议一个快速而肮脏的解决方案:

您可以在图像视图下方添加另一个白色视图,而不是在图像视图中添加边框。 使视图在任一方向上延伸10个点,并使其角半径为20.0。 为图像视图指定角半径10.0。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM