遮罩UIImageView中的甜甜圈形状

时间:2018-08-27 10:43:06

标签: ios uiimageview cashapelayer

我正在尝试将甜甜圈形状切成UIImageView。我目前只能像这样实现圆形切口:

import UIKit
import CoreGraphics

class AvatarImageView: UIImageView {

    enum AvatarImageViewOnlineStatus {
        case online
        case offline
        case hidden
    }

    var rounded: Bool = false
    var onlineStatus: AvatarImageViewOnlineStatus = .hidden

    override func layoutSubviews() {
        super.layoutSubviews()
        guard !rounded else { return }
        if let image = image, !rounded {
            self.image = image.af_imageRoundedIntoCircle()
            rounded = true
        }

        let rect: CGRect = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)
        let maskLayer: CAShapeLayer = CAShapeLayer()
        maskLayer.frame = rect

        let mainPath: UIBezierPath = UIBezierPath(rect: rect)
        let circlePath: UIBezierPath = UIBezierPath(ovalIn: CGRect(x: 20, y: 20, width: 30, height: 30))
        mainPath.append(circlePath)

        maskLayer.fillRule = kCAFillRuleEvenOdd
        maskLayer.path = mainPath.cgPath
        maskLayer.strokeColor = UIColor.clear.cgColor
        maskLayer.lineWidth = 10.0
        layer.mask = maskLayer
    }

}

enter image description here

是否可以使用面罩创建甜甜圈形的切口?

1 个答案:

答案 0 :(得分:1)

这比我期望的要花费更多的精力,并且解决方案并不明显...直到找到它,然后,就像,哦,是的,确定:/

“基本”想法是,您想“切出”现有路径的一部分,解决方案并不明显,因为UIBezierPath没有提供“减”或“删除”方法。相反,您需要“反转”路径,例如...

let path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 200, height: 200))
path.append(UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 100, height: 100)).reversing())
path.append(UIBezierPath(ovalIn: CGRect(x: 75, y: 75, width: 50, height: 50)))

而且,因为“上下文外”片段很少有帮助,所以这是我用来测试它的操场(提供自己的图像)...

import UIKit
import Foundation
import CoreGraphics

let image = UIImage(named: "Profile")
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
backgroundView.backgroundColor = UIColor.green
backgroundView.addSubview(imageView)

imageView.contentMode = .scaleAspectFit
imageView.image = image
imageView.layer.cornerRadius = 100

let shapeLayer = CAShapeLayer()

let path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 200, height: 200))
path.append(UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 100, height: 100)).reversing())
path.append(UIBezierPath(ovalIn: CGRect(x: 75, y: 75, width: 50, height: 50)))

shapeLayer.path = path.cgPath
shapeLayer.fillColor = UIColor.red.cgColor
shapeLayer.frame = imageView.bounds

imageView.layer.mask = shapeLayer
backgroundView

我的结果...

Those are the droids you're looking for

绿色来自backgroundView所在的UIImageView

现在,如果您更喜欢...

I can't see anything out of this helmet

然后删除第二个append语句path.append(UIBezierPath(ovalIn: CGRect(x: 75, y: 75, width: 50, height: 50)))