I have been exploring this questions through playgrounds for days now without finding any solution.
I am been managing to create a hole in a blurred UIView. Now I am wondering how to animate the radius of this circle, ergo animating the blurred view's mask's path.
Here is my code so far:
import Foundation
import UIKit
import PlaygroundSupport
let contentRect = CGRect(x: 0, y: 0, width: 400, height: 400)
let contentView = UIView(frame: contentRect)
contentView.backgroundColor = .white
PlaygroundPage.current.liveView = contentView
let image = UIImage(named: "landscape.jpg")
let imageView = UIImageView(frame: contentRect, image: image)
imageView.contentMode = .scaleAspectFill
let blur = UIBlurEffect(style: .light)
let blurView = UIVisualEffectView(effect: blur)
blurView.frame = contentRect
let path = UIBezierPath(rect: contentRect)
let circle = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 300, height: 300))
path.append(circle)
path.usesEvenOddFillRule = true
let toPath = UIBezierPath(rect: contentRect)
let toCircle = UIBezierPath(ovalIn: CGRect(x: 150, y: 150, width: 100, height: 100))
toPath.append(toCircle)
toPath.usesEvenOddFillRule = true
let hole = CAShapeLayer()
hole.path = path.cgPath
hole.fillColor = UIColor.green.cgColor
hole.fillRule = kCAFillRuleEvenOdd
let mask = UIView(frame: contentRect)
contentView.addSubview(imageView)
contentView.addSubview(blurView)
mask.layer.addSublayer(hole)
blurView.mask = mask
I have been trying this, without success:
let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = hole.path
animation.toValue = toPath.cgPath
animation.duration = 2
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
hole.add(animation, forKey: nil)
CATransaction.begin()
CATransaction.disableActions()
hole.path = toPath.cgPath
CATransaction.commit()
Also tried UIView.animate(... or extracting blurView.layer.sublayers to add them to my contentView, but it just gets messy.
Another approach would be to use a CGAffineTransform, which I tried, but the blur gets disrupted. Plus I have trouble to use a workaround when I feel so close to a solution.
Any help would be greatly appreciated! Thanks!
Related
I have been trying to implement this answer from this question using Swift 5.2
I only see the blurred image and the mask is not appearing. Can someone point me what I am missing there or how to convert it to Swift 5 from Swift 3?
This is a playground code.
import UIKit
import PlaygroundSupport
let generalFrame = CGRect(x: 0, y: 0, width: 500, height: 500)
let containerView = UIView(frame: generalFrame)
containerView.backgroundColor = UIColor.black;
PlaygroundPage.current.liveView = containerView
let parentView = UIView(frame: generalFrame)
containerView.addSubview(parentView)
let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")
let data = try Data(contentsOf: url!);
let imageView = UIImageView(frame:parentView.bounds)
imageView.image = UIImage(data: data)
imageView.contentMode = .scaleAspectFill
let maskView = UIView(frame:parentView.bounds)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = {() -> CALayer in
var roundedRect = CGRect (
x: 0.0,
y: 0.0,
width: parentView.bounds.size.width * 0.5,
height: parentView.bounds.size.width * 0.5
);
roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;
let cornerRadius = roundedRect.size.height / 2.0;
let path = UIBezierPath(rect:parentView.bounds)
let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
path.append(croppedPath)
path.usesEvenOddFillRule = true
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath;
maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
return maskLayer
}()
let blurView = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blurView)
effectView.frame = generalFrame
effectView.mask = maskView
parentView.addSubview(imageView)
parentView.addSubview(effectView)
I managed to get this working. The fix was to apply mask to UIVisualEffectView:
let maskLayer = CAShapeLayer()
effectView.layer.mask = maskLayer
import UIKit
import PlaygroundSupport
let generalFrame = CGRect(x: 0, y: 0, width: 500, height: 500)
let containerView = UIView(frame: generalFrame)
containerView.backgroundColor = UIColor.black;
PlaygroundPage.current.liveView = containerView
let parentView = UIView(frame: generalFrame)
containerView.addSubview(parentView)
let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")
let data = try Data(contentsOf: url!);
let imageView = UIImageView(frame:parentView.bounds)
imageView.image = UIImage(data: data)
imageView.contentMode = .scaleAspectFill
var roundedRect = CGRect (
x: 0.0,
y: 0.0,
width: parentView.bounds.size.width * 0.5,
height: parentView.bounds.size.width * 0.5
);
roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;
let cornerRadius = roundedRect.size.height / 2.0;
let path = UIBezierPath(rect:parentView.bounds)
let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
path.append(croppedPath)
path.usesEvenOddFillRule = true
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath;
maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
let blurView = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blurView)
effectView.frame = generalFrame
effectView.layer.mask = maskLayer
parentView.addSubview(imageView)
parentView.addSubview(effectView)
Any possibility in having a rounded corner for a view container without using masksToBounds = true ?
signup.layer.cornerRadius = 10
signup.layer.masksToBounds = false
Yes, you can but you may have to write following code:
let containerView = UIView(frame: CGRect(x: 100.0, y: 100.0, width: 200.0, height: 200.0))
containerView.backgroundColor = UIColor.clear
let aPath = UIBezierPath(roundedRect: containerView.bounds, cornerRadius: 10.0)
aPath.lineWidth = 1.0
aPath.stroke()
let layer = CAShapeLayer()
layer.fillColor = UIColor.red.cgColor
layer.strokeColor = UIColor.red.cgColor
layer.path = aPath.cgPath
containerView.layer.addSublayer(layer)
self.view.addSubview(containerView)
I am creating an overlay of blurredView with a clear rectangle cutout in the middle. My code so far has achieved the opposite, ie a clearView with a blur cutout in the middle instead.
I have adapted my steps from the following posts, I appreciate if anyone could point me in the right direction.
Swift mask of circle layer over UIView
CALayer with transparent hole in it
let blurView = UIVisualEffectView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
blurView.effect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let scanLayer = CAShapeLayer()
scanLayer.path = CGPath(rect: scanRect, transform: nil)
view.addSubview(blurView)
blurView.layer.addSublayer(scanLayer)
blurView.layer.mask = scanLayer
You can do it like this
let scanLayer = CAShapeLayer()
let scanRect = CGRect.init(x: 100, y: 100, width: 200, height: 100)
let outerPath = UIBezierPath(rect: scanRect)
let superlayerPath = UIBezierPath.init(rect: blurView.frame)
outerPath.usesEvenOddFillRule = true
outerPath.append(superlayerPath)
scanLayer.path = outerPath.cgPath
scanLayer.fillRule = kCAFillRuleEvenOdd
scanLayer.fillColor = UIColor.black.cgColor
view.addSubview(blurView)
blurView.layer.mask = scanLayer
I've make a path in order to mask my view:
let path = // create magic path (uiview bounds + 2 arcs)
let mask = CAShapeLayer()
mask.path = path.cgPath
view.layer.masksToBounds = false
view.layer.mask = mask
Up to here all ok.
Now I would like to add a shadow that follows path, is it possibile?
I try in several way, the last one is:
mask.shadowPath = path.cgPath
mask.shadowColor = UIColor.red.cgColor
mask.shadowOffset = CGSize(width: 10, height: 2.0)
mask.shadowOpacity = 0.5
But this produce a partial shadow and with color of the original view..
With debug view hierarchy:
Any advice?
Final result should be similar to this, but with shadow that "follows" arcs on path.
When you add a mask to a layer, it clips anything outside that mask - including the shadow. To achieve this you'll need to add a "shadow" view below your masked view, that has the same path as the mask.
Or add a shadow layer to the masked view's superview.
let view = UIView(frame: CGRect(x: 50, y: 70, width: 100, height: 60))
view.backgroundColor = .cyan
let mask = CAShapeLayer()
mask.path = UIBezierPath(roundedRect: view.bounds, cornerRadius: 10).cgPath
view.layer.mask = mask
let shadowLayer = CAShapeLayer()
shadowLayer.frame = view.frame
shadowLayer.path = UIBezierPath(roundedRect: view.bounds, cornerRadius: 10).cgPath
shadowLayer.shadowOpacity = 0.5
shadowLayer.shadowRadius = 5
shadowLayer.masksToBounds = false
shadowLayer.shadowOffset = .zero
let container = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
container.backgroundColor = .white
container.layer.addSublayer(shadowLayer)
container.addSubview(view)
If you're going to be using this elsewhere, you could create a ShadowMaskedView that contains the shadow layer, and the masked view - maybe with a path property.
You can try this extension:
extension UIView {
func dropShadow() {
self.layer.masksToBounds = false
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOpacity = 0.5
self.layer.shadowOffset = CGSize(width: -1, height: 1)
self.layer.shadowRadius = 1
self.layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
self.layer.shouldRasterize = true
}
}
I have an app I created that uses UIBlurEffectView that worked perfect on iOS 9 and under, but when I upgraded my device (a few of them, not just 1 device) the blur disappeared and instead of the blur there is a half-transperant view for some reason.
Does anything changed in this class? Anyone knows why?
My code (The view is a shape from SVG file that I'm getting using PocketSVG API):
let blur: UIBlurEffect = UIBlurEffect(style: .Light)
let ev: UIVisualEffectView = UIVisualEffectView(effect: blur)
ev.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(ev)
ev.rightAnchor.constraintEqualToAnchor(self.rightAnchor).active = true
ev.bottomAnchor.constraintEqualToAnchor(self.bottomAnchor).active = true
ev.leftAnchor.constraintEqualToAnchor(self.leftAnchor).active = true
ev.heightAnchor.constraintEqualToAnchor(self.heightAnchor, multiplier: 1.5).active = true
let myPath: CGPathRef = PocketSVG.pathFromSVGFileNamed("CategoriesBar").takeUnretainedValue()
var transform: CGAffineTransform = CGAffineTransformMakeScale(self.frame.size.width / 754.0, self.frame.size.height / 220.0)
let transformedPath: CGPathRef = CGPathCreateMutableCopyByTransformingPath(myPath, &transform)!
let myShapeLayer = CAShapeLayer()
myShapeLayer.path = transformedPath
self.layer.mask = myShapeLayer
Leo Natan's answer code:
What you've suggested doesn't work, here is the code
override func layoutSubviews() {
let blur: UIBlurEffect = UIBlurEffect(style: .Light)
let ev: UIVisualEffectView = UIVisualEffectView(effect: blur)
ev.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(ev)
ev.rightAnchor.constraintEqualToAnchor(self.rightAnchor).active = true
ev.bottomAnchor.constraintEqualToAnchor(self.bottomAnchor).active = true
ev.leftAnchor.constraintEqualToAnchor(self.leftAnchor).active = true
ev.heightAnchor.constraintEqualToAnchor(self.heightAnchor, multiplier: 1.5).active = true
let myPath: CGPathRef = PocketSVG.pathFromSVGFileNamed("CategoriesBar").takeUnretainedValue()
var transform: CGAffineTransform = CGAffineTransformMakeScale(self.frame.size.width / 754.0, self.frame.size.height / 220.0)
let transformedPath: CGPathRef = CGPathCreateMutableCopyByTransformingPath(myPath, &transform)!
let myShapeLayer = CAShapeLayer()
myShapeLayer.path = transformedPath
self.layer.mask = myShapeLayer
let myMaskedView = UIView(frame: ev.frame)
myMaskedView.layer.mask = myShapeLayer
ev.maskView = myMaskedView
}
Konrad Siemczyk answer code
override func layoutSubviews() {
let blur: UIBlurEffect = UIBlurEffect(style: .Light)
let ev: UIVisualEffectView = UIVisualEffectView(effect: blur)
ev.frame = self.bounds
ev.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(ev)
ev.rightAnchor.constraintEqualToAnchor(self.rightAnchor).active = true
ev.bottomAnchor.constraintEqualToAnchor(self.bottomAnchor).active = true
ev.leftAnchor.constraintEqualToAnchor(self.leftAnchor).active = true
ev.heightAnchor.constraintEqualToAnchor(self.heightAnchor, multiplier: 1.5).active = true
let myPath: CGPathRef = PocketSVG.pathFromSVGFileNamed("CategoriesBar").takeUnretainedValue()
var transform: CGAffineTransform = CGAffineTransformMakeScale(self.frame.size.width / 754.0, self.frame.size.height / 220.0)
let transformedPath: CGPathRef = CGPathCreateMutableCopyByTransformingPath(myPath, &transform)!
let myShapeLayer = CAShapeLayer()
myShapeLayer.path = transformedPath
//self.layer.mask = myShapeLayer
myShapeLayer.fillRule = kCAFillRuleEvenOdd
let myMaskedView = UIView(frame: self.frame)
myMaskedView.backgroundColor = UIColor.blackColor()
myMaskedView.layer.mask = myShapeLayer
ev.maskView = myMaskedView
}
Hey, before implementing this one...
TLDR: Please check this solution first:
https://stackoverflow.com/a/67939549/2829540
... even though these examples work on older versions of iOS, looks like newer ones require a layer instead of a view, this answer might not work as expected. You might need to implement this solution for older versions and the linked one for newer ones.
For ObjectiveC users out there.
Here is a working example for iOS 10.
I also attached the resulting view at the end. I am adding the white border on top later. The cropped circle masking is in the code, if you like it use it as is.
// "self" in here is an UIView that contains some images inside.
{
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurredEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
CGRect frame = self.frame;
frame.origin = CGPointMake (0, 0);
blurredEffectView.frame = frame;
[self addSubview:blurredEffectView];
UIView *maskView = [[UIView alloc] initWithFrame:frame];
maskView.backgroundColor = [UIColor blackColor];
__weak UIView *weak = self;
maskView.layer.mask = ({ // This mask draws a rectangle and crops a circle inside it.
__strong UIView *strong = weak;
CGRect roundedRect = CGRectMake (
0,
0,
strong.frame.size.width * 0.8f,
strong.frame.size.width * 0.8f
);
roundedRect.origin.x = strong.frame.size.width / 2 - roundedRect.size.width / 2;
roundedRect.origin.y = strong.frame.size.height / 2 - roundedRect.size.height / 2;
CGFloat cornerRadius = roundedRect.size.height / 2.0f;
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.bounds];
UIBezierPath *croppedPath = [UIBezierPath bezierPathWithRoundedRect:roundedRect cornerRadius:cornerRadius];
[path appendPath:croppedPath];
[path setUsesEvenOddFillRule:YES];
CAShapeLayer *mask = [CAShapeLayer layer];
mask.path = path.CGPath;
mask.fillRule = kCAFillRuleEvenOdd;
mask;
});
blurredEffectView.maskView = maskView;
}
So, this is same code as Swift 3 for testing in playground.
This is using a try while downloading the url, so it is synchronous
import UIKit
import PlaygroundSupport
let generalFrame = CGRect(x: 0, y: 0, width: 500, height: 500)
let containerView = UIView(frame: generalFrame)
containerView.backgroundColor = UIColor.black;
PlaygroundPage.current.liveView = containerView
let parentView = UIView(frame: generalFrame)
containerView.addSubview(parentView)
let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")
let data = try Data(contentsOf: url!);
let imageView = UIImageView(frame:parentView.bounds)
imageView.image = UIImage(data: data)
imageView.contentMode = .scaleAspectFill
let maskView = UIView(frame:parentView.bounds)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = {() -> CALayer in
var roundedRect = CGRect (
x: 0.0,
y: 0.0,
width: parentView.bounds.size.width * 0.5,
height: parentView.bounds.size.width * 0.5
);
roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;
let cornerRadius = roundedRect.size.height / 2.0;
let path = UIBezierPath(rect:parentView.bounds)
let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
path.append(croppedPath)
path.usesEvenOddFillRule = true
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath;
maskLayer.fillRule = kCAFillRuleEvenOdd
return maskLayer
}()
let blurView = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blurView)
effectView.frame = generalFrame
effectView.mask = maskView
parentView.addSubview(imageView)
parentView.addSubview(effectView)
And working example in a view controller:
This one downloads an image first then appends the blur effect.
import UIKit
class ViewController: UIViewController {
func addTheBlurView(data :Data) {
let generalFrame = self.view.bounds;
let parentView = UIView(frame: generalFrame)
self.view.addSubview(parentView)
let imageView = UIImageView(frame: parentView.bounds)
imageView.image = UIImage(data: data)
imageView.contentMode = .scaleAspectFill
let maskView = UIView(frame: parentView.bounds)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = {
() -> CALayer in
var roundedRect = CGRect(
x: 0.0,
y: 0.0,
width: parentView.bounds.size.width * 0.5,
height: parentView.bounds.size.width * 0.5
);
roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;
let cornerRadius = roundedRect.size.height / 2.0;
let path = UIBezierPath(rect: parentView.bounds)
let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
path.append(croppedPath)
path.usesEvenOddFillRule = true
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath;
maskLayer.fillRule = kCAFillRuleEvenOdd
return maskLayer
}()
let blurView = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blurView)
effectView.frame = generalFrame
effectView.mask = maskView
parentView.addSubview(imageView)
parentView.addSubview(effectView)
}
override func viewDidLoad() {
debugPrint("Running...")
super.viewDidLayoutSubviews();
// Lets load an image first, so blur looks cool
let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")
URLSession.shared.dataTask(with: url!) {
(data, response, error) in
if error != nil {
print(error)
return
}
DispatchQueue.main.async(execute: {
self.addTheBlurView(data: data!)
})
}.resume()
}
}
OBJECTIVEC VERSION
PLAYGROUND VERSION
VIEWCONTROLLER VERSION
If you're looking for a solution with masked view and blur in Swift 3.0, look at code below:
class func addBlurredView(_ forView: UIView, centeredElement: UIView) {
let blur = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blur.frame = forView.frame
blur.isUserInteractionEnabled = false
forView.addSubview(blur)
let radius = centeredElement.bounds.width / 2
let path = UIBezierPath (
roundedRect: blur.frame,
cornerRadius: 0)
let circle = UIBezierPath (
roundedRect: CGRect(origin: CGPoint(x: centeredElement.frame.origin.x, y: centeredElement.frame.origin.y),
size: centeredElement.frame.size), cornerRadius: radius)
path.append(circle)
path.usesEvenOddFillRule = true
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
maskLayer.fillRule = kCAFillRuleEvenOdd
let maskView = UIView(frame: forView.frame)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = maskLayer
blur.mask = maskView
}
Thanks to #emrahgunduz answer I managed to update the above code to Swift 5.2.
import UIKit
import PlaygroundSupport
let generalFrame = CGRect(x: 0, y: 0, width: 500, height: 500)
let containerView = UIView(frame: generalFrame)
containerView.backgroundColor = UIColor.black;
PlaygroundPage.current.liveView = containerView
let parentView = UIView(frame: generalFrame)
containerView.addSubview(parentView)
let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")
let data = try Data(contentsOf: url!);
let imageView = UIImageView(frame:parentView.bounds)
imageView.image = UIImage(data: data)
imageView.contentMode = .scaleAspectFill
var roundedRect = CGRect (
x: 0.0,
y: 0.0,
width: parentView.bounds.size.width * 0.5,
height: parentView.bounds.size.width * 0.5
);
roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;
let cornerRadius = roundedRect.size.height / 2.0;
let path = UIBezierPath(rect:parentView.bounds)
let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
path.append(croppedPath)
path.usesEvenOddFillRule = true
let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath;
maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
let blurView = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blurView)
effectView.frame = generalFrame
effectView.layer.mask = maskLayer
parentView.addSubview(imageView)
parentView.addSubview(effectView)
According to a discussion with Apple engineer, this is a limitation to how the UIVisualEffectView works. It used to work before, but UIVisualEffectView was less accurate.
The suggested approach in the discussion is to use maskView instead of masking the layer directly. So try creating a view, mask that view's layer, and set that as the mask view.
let myMaskedView = UIView(frame: ev.frame)
myMaskedView.layer.mask = myShapeLayer
ev.maskView = myMaskedView
This code is tested and it is work on Ipad Air 2 simulator iOS 10.0
class BlurView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
self.initialView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialView()
}
func initialView() {
if UIAccessibilityIsReduceTransparencyEnabled() == false {
self.backgroundColor = UIColor.clearColor()
let blurEffect = UIBlurEffect(style: .Dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = self.bounds
blurEffectView.translatesAutoresizingMaskIntoConstraints = true
blurEffectView.autoresizingMask = UIViewAutoresizing.FlexibleWidth.union(.FlexibleHeight)
self.addSubview(blurEffectView)
} else {
self.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.5)
}
}
}
You can use it on storyboard or create it using code.