簡體   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