Search code examples
iosswiftuiviewmask

UIView with multiple masks


I currently have a UIView with a gradient mask:

let maskLayer = CAGradientLayer()
maskLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
let innerColor = UIColor(white: 1.0, alpha: 1.0).cgColor
let outerColor = UIColor(white: 1.0, alpha: 0.0).cgColor
maskLayer.colors = [outerColor, innerColor, innerColor, outerColor]
maskLayer.locations = [0.0, 0.20, 0.80, 1.00]
maskLayer.startPoint = CGPointMake(0.5, 0);
maskLayer.endPoint = CGPointMake(0.5, 1);
self.myView.layer.mask = maskLayer

This adds a gradient mask to the top and bottom of the view successfully.

Question

Is there a way for me to add an additional circle mask (non-gradient) to the center of the view?


Solution

  • You can create a parent/container layer and add all the mask layer's as it's sublayer.

    let containerMaskLayer = CALayer()
    
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = CGRect(x: 0, y: 0, width: 300, height: 500)
    let innerColor = UIColor(white: 1.0, alpha: 1.0).cgColor
    let outerColor = UIColor(white: 1.0, alpha: 0.0).cgColor
    gradientLayer.colors = [outerColor, innerColor, innerColor, outerColor]
    gradientLayer.locations = [0.0, 0.20, 0.80, 1.00]
    gradientLayer.startPoint = CGPointMake(0.5, 0);
    gradientLayer.endPoint = CGPointMake(0.5, 1);
    containerMaskLayer.addSublayer(gradientLayer)
    
    let circleLayer = CAShapeLayer()
    let radius: CGFloat = 100.0
    circleLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 2.0 * radius, height: 2.0 * radius), cornerRadius: radius).cgPath
    circleLayer.position = CGPoint(x: 100 - radius, y: 100 - radius)
    circleLayer.fillColor = UIColor.white.cgColor
    containerMaskLayer.addSublayer(circleLayer)
    
    view.layer.mask = containerMaskLayer