2014-10-27 80 views
2

在下圖中,藍色圓圈僅用於調試目的。我的目標是藍色圓圈後面的每一層都應該是透明的。我只想保持藍色圓圈外面的內容。摘要CALayer從另一個混合?

enter image description here

這是寫在SWIFT代碼:

let croissantView = UIView(frame: CGRectMake(100, 100, 100, 100)) 
    croissantView.backgroundColor = UIColor.clearColor() 

    self.view.addSubview(croissantView) 


    let radius = 50 as CGFloat 
    let width = 50 as CGFloat 

    let origin = CGPointMake(0, 100) 
    let end = CGPointMake(100,100) 
    let highAmplitude = CGPointMake(50,180) 
    let lowAmplitude = CGPointMake(50,150) 

    let quad = UIBezierPath() 
    quad.moveToPoint(origin) 
    quad.addQuadCurveToPoint(end, controlPoint: highAmplitude) 
    quad.closePath() 

    let quad2 = UIBezierPath() 
    quad2.moveToPoint(origin) 
    quad2.addQuadCurveToPoint(end, controlPoint: lowAmplitude) 
    quad2.closePath() 

    let layer = CAShapeLayer() 
    layer.path = quad.CGPath 

    layer.strokeColor = UIColor.greenColor().CGColor 
    layer.fillColor = UIColor.blackColor().CGColor 

    croissantView.layer.addSublayer(layer) 

    let anim = CABasicAnimation(keyPath: "path") 
    anim.duration = 3 
    anim.repeatCount = 20 
    anim.fromValue = quad.CGPath 
    anim.toValue = quad2.CGPath 
    anim.autoreverses = true 
    layer.addAnimation(anim, forKey: "animQuad") 


    let animRotate = CABasicAnimation(keyPath: "transform.rotation") 
    animRotate.duration = 5 
    animRotate.repeatCount = 20 
    animRotate.fromValue = 0 
    animRotate.toValue = 360 * CGFloat(M_PI)/180 
    croissantView.layer.addAnimation(animRotate, forKey: "animRotate") 


    let circle = UIBezierPath(arcCenter: croissantView.center, radius: 75, startAngle: 0, endAngle: 360 * CGFloat(M_PI)/180, clockwise: true); 
    let circleLayer = CAShapeLayer() 
    circleLayer.path = circle.CGPath 
    circleLayer.fillColor = UIColor.blueColor().CGColor 
    circleLayer.opacity = 0.6 
    self.view.layer.addSublayer(circleLayer) 
思考
  • 從層。減去,不知道是否可行
  • 混合,不知道如何用CALayer做吧

謝謝! :)

+0

你看過[CALayer的''mask'屬性]嗎?(https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CALayer_class/index.html#//apple_ref/occ/instp/CALayer的/掩模)? – 2014-10-27 22:13:44

回答

2

我會建議三件事。

  1. 您的羊角麪包視圖更改爲層(不知道這是必要的,但是這是我做的)

  2. 對於可以面具倒你的圓形創建CGPath。您可以通過在你的圈子包裹外矩形這樣做,這樣的路徑是這樣的:

enter image description here

  • 設置你的填充規則的圓形層上到奇偶:

    circleLayer.fillRule = kCAFillRuleEvenOdd 
    
  • 這是什麼樣子:

    enter image description here

    我調整了你的代碼來嘗試它,這就是我想出來的。你的情況可能有所不同:

    func applyMask() { 
    
        let mainLayer = CALayer() 
        mainLayer.bounds = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0) 
        mainLayer.position = CGPoint(x: 200.0, y: 200.0) 
        // Set the color for debugging 
        mainLayer.backgroundColor = UIColor.orangeColor().CGColor 
    
        self.view.layer.addSublayer(mainLayer) 
    
        let radius = 50 as CGFloat 
        let width = 50 as CGFloat 
    
        let origin = CGPointMake(0, 100) 
        let end = CGPointMake(100,100) 
        let highAmplitude = CGPointMake(50,180) 
        let lowAmplitude = CGPointMake(50,150) 
    
        let quad = UIBezierPath() 
        quad.moveToPoint(origin) 
        quad.addQuadCurveToPoint(end, controlPoint: highAmplitude) 
        quad.closePath() 
    
        let quad2 = UIBezierPath() 
        quad2.moveToPoint(origin) 
        quad2.addQuadCurveToPoint(end, controlPoint: lowAmplitude) 
        quad2.closePath() 
    
        let layer = CAShapeLayer() 
        layer.path = quad.CGPath 
    
        layer.strokeColor = UIColor.greenColor().CGColor 
        layer.fillColor = UIColor.blackColor().CGColor 
    
        mainLayer.addSublayer(layer) 
    
        let anim = CABasicAnimation(keyPath: "path") 
        anim.duration = 3 
        anim.repeatCount = 20 
        anim.fromValue = quad.CGPath 
        anim.toValue = quad2.CGPath 
        anim.autoreverses = true 
        layer.addAnimation(anim, forKey: "animQuad") 
    
        let animRotate = CABasicAnimation(keyPath: "transform.rotation") 
        animRotate.duration = 5 
        animRotate.repeatCount = 20 
        animRotate.fromValue = 0 
        animRotate.toValue = 360 * CGFloat(M_PI)/180 
        mainLayer.addAnimation(animRotate, forKey: "animRotate") 
    
        // Build a Circle CGPath 
        var circlePath = CGPathCreateMutable() 
        CGPathAddEllipseInRect(circlePath, nil, CGRectInset(mainLayer.bounds, -20.0, -20.0)) 
        // Invert the mask by adding a bounding rectangle 
        CGPathAddRect(circlePath, nil, CGRectInset(mainLayer.bounds, -100.0, -100.0)) 
        CGPathCloseSubpath(circlePath) 
    
        let circleLayer = CAShapeLayer() 
        circleLayer.fillColor = UIColor.blueColor().CGColor 
        circleLayer.opacity = 0.6 
        // Use the even odd fill rule so that our path gets inverted 
        circleLayer.fillRule = kCAFillRuleEvenOdd 
        circleLayer.path = circlePath 
    
        mainLayer.mask = circleLayer 
    
        mainLayer.addSublayer(layer) 
    } 
    

    這裏的項目中,我嘗試過了:https://github.com/perlmunger/SwiftVertedMask

    希望有所幫助。

    +0

    非常感謝!它工作完美!我是goona玩它肯定理解一切。 – 2014-10-28 07:55:21