Swift - 带三角形的模糊圆圈 - 模糊效果始终位于顶部

Swift - Blur Circle with a triangle - Blur Effect is always at top

我正在尝试创建一个简单的圆形按钮并在该按钮内放置一个三角形,它实际上是一个播放按钮。问题是,当我将 BlurEffect 添加到按钮时,它始终位于顶部并且会隐藏三角形。有没有办法在模糊效果上方添加三角形?

import UIKit

@IBDesignable
class CirclePlayButton: UIButton {

    let blur = UIBlurEffect(style: .Light)

    override func drawRect(rect: CGRect) {
        let blurEffect = UIVisualEffectView(effect: blur)
        blurEffect.alpha = 0.9
        //self.addSubview(blurEffect)
        self.insertSubview(blurEffect, atIndex: 0)
        let path = UIBezierPath(ovalInRect: rect)
        blurEffect.frame = path.bounds


        let mask = CAShapeLayer()
        mask.path = path.CGPath
        blurEffect.layer.mask = mask


        let trianglePath = UIBezierPath()
        trianglePath.lineWidth = 2
        trianglePath.moveToPoint(CGPoint(x: bounds.width*1/4+5, y: bounds.height/4))
        trianglePath.addLineToPoint(CGPoint(x: bounds.width*3/4+5, y: bounds.height/2))
        trianglePath.addLineToPoint(CGPoint(x: bounds.width*1/4+5, y: bounds.height*3/4))
        trianglePath.addLineToPoint(CGPoint(x: bounds.width*1/4+5, y: bounds.height/4))
        UIColor.blackColor().setStroke()
        trianglePath.stroke()
    }
}

提前致谢。

找到解决方案

import UIKit

@IBDesignable
class CirclePlayButton: UIButton {

    @IBInspectable var fillColor: UIColor = UIColor.clearColor()
    @IBInspectable var lineColor: UIColor = UIColor.blackColor()
    var constantSize: CGFloat = 0.30
    var spaceX: CGFloat = 5
    @IBInspectable var percentSize: CGFloat {
        set(newValue){
            if newValue >= 0 && newValue <= 100{
                constantSize = newValue / 100
            } else {
                constantSize = 0.30
            }
        } get{
            return constantSize
        }
    }

    @IBInspectable var addSpace: CGFloat{
        set(newValue){
            if newValue >= 0 && newValue <= 10{
                spaceX = newValue
            } else {
                spaceX = 0
            }
        }get {
            return spaceX
        }
    }

    let blur: UIBlurEffect = UIBlurEffect(style: .Light)

    override func drawRect(rect: CGRect) {
        let topX = (bounds.width * constantSize) + spaceX
        let topY = bounds.height * constantSize

        let middleX = (bounds.width * (1 - constantSize)) + spaceX
        let middleY = bounds.height * 0.5

        let bottomX = topX
        let bottomY = bounds.height * (1 - constantSize)



        let blurEffect = UIVisualEffectView(effect: blur)
        blurEffect.alpha = 0.9
        let path = UIBezierPath(ovalInRect: rect)

        blurEffect.frame = path.bounds
        let mask = CAShapeLayer()
        mask.path = path.CGPath
        blurEffect.layer.mask = mask
        self.insertSubview(blurEffect, atIndex: 0)

        let trianglePath = UIBezierPath()
        trianglePath.lineJoinStyle = .Round

        trianglePath.moveToPoint(CGPoint(x: topX, y: topY))
        trianglePath.addLineToPoint(CGPoint(x: middleX, y: middleY))
        trianglePath.addLineToPoint(CGPoint(x: bottomX, y: bottomY))
        trianglePath.addLineToPoint(CGPoint(x: topX, y: topY))

        let maskImage = CAShapeLayer()
        maskImage.path = trianglePath.CGPath
        maskImage.lineJoin = kCALineJoinRound
        maskImage.lineWidth = 2
        maskImage.fillColor = fillColor.CGColor
        maskImage.strokeColor = lineColor.CGColor

        self.layer.addSublayer(maskImage)
    }
}

更新为 Swift 3.1

@IBDesignable
class CirclePlayButton: UIButton {

@IBInspectable var fillColor: UIColor = UIColor.clear
@IBInspectable var lineColor: UIColor = UIColor.black
var constantSize: CGFloat = 0.30
var spaceX: CGFloat = 5
@IBInspectable var percentSize: CGFloat {
    set(newValue){
        if newValue >= 0 && newValue <= 100{
            constantSize = newValue / 100
        } else {
            constantSize = 0.30
        }
    } get{
        return constantSize
    }
}

@IBInspectable var addSpace: CGFloat{
    set(newValue){
        if newValue >= 0 && newValue <= 10{
            spaceX = newValue
        } else {
            spaceX = 0
        }
    }get {
        return spaceX
    }
}

let blur: UIBlurEffect = UIBlurEffect(style: .light)

override func draw(_ rect: CGRect) {
    let topX = (bounds.width * constantSize) + spaceX
    let topY = bounds.height * constantSize

    let middleX = (bounds.width * (1 - constantSize)) + spaceX
    let middleY = bounds.height * 0.5

    let bottomX = topX
    let bottomY = bounds.height * (1 - constantSize)



    let blurEffect = UIVisualEffectView(effect: blur)
    blurEffect.alpha = 0.9
    let path = UIBezierPath(ovalIn: rect)

    blurEffect.frame = path.bounds
    let mask = CAShapeLayer()
    mask.path = path.cgPath
    blurEffect.layer.mask = mask
    self.insertSubview(blurEffect, at: 0)

    let trianglePath = UIBezierPath()
    trianglePath.lineJoinStyle = .round

    trianglePath.move(to: CGPoint(x: topX, y: topY))
    trianglePath.addLine(to: CGPoint(x: middleX, y: middleY))
    trianglePath.addLine(to: CGPoint(x: bottomX, y: bottomY))
    trianglePath.addLine(to: CGPoint(x: topX, y: topY))

    let maskImage = CAShapeLayer()
    maskImage.path = trianglePath.cgPath
    maskImage.lineJoin = kCALineJoinRound
    maskImage.lineWidth = 2
    maskImage.fillColor = fillColor.cgColor
    maskImage.strokeColor = lineColor.cgColor

    self.layer.addSublayer(maskImage)
}
}