Before asking this question, I found so many answers at stack overflow but none worked for my case.
Requirement:
I tried:
private func setShadow() {
contentView.layer.masksToBounds = false
contentView.layer.shadowOffset = CGSize(width: 0, height: 1.5)
contentView.layer.shadowRadius = 0.5
contentView.layer.shadowOpacity = 0.5
layer.shadowColor = UIColor.lightGray.cgColor
}
I also play around with offset, radius, opacity; studied about each property, but none combination results in desired output. Any suggestions please.
You can achieve the effect by static layer.
contentView.layer.masksToBounds = false
let shadowLayer = CALayer()
shadowLayer.frame = contentView.bounds
shadowLayer.shadowOffset = CGSize(width: 0, height: 1.5);
shadowLayer.shadowRadius = 0.5
shadowLayer.shadowOpacity = 0.5;
shadowLayer.shadowColor = UIColor.lightGray.cgColor
contentView.layer.addSublayer(shadowLayer)
Please remember to input it in layoutSubviews if you use autolayout .
override func layoutSubviews() {
super.layoutSubviews()
shadowLayer.frame = contentView.bounds
}
Related
I have collectionview cell to which I have a container UIView() which is margined at some distance from the super view. The containerview is rounded and I am trying to apply drop shadow to it. I am acheiving this quite finely until, on some cells it breaks the shadow layer and creates and uneven shadow effect. Following is the current result.:
Following is my code:
extension UIView() {
func dropShadow(color: UIColor, opacity: Float = 0.5, offSet: CGSize, radius: CGFloat = 1, scale: Bool = true) {
self.layer.masksToBounds = false
self.layer.shadowColor = color.cgColor
self.layer.shadowOpacity = opacity
self.layer.shadowOffset = offSet
self.layer.shadowRadius = radius
self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: radius).cgPath
self.layer.shouldRasterize = true
self.layer.rasterizationScale = scale ? UIScreen.main.scale : 1
}
}
Following is UICollectionViewCell.swift
override func layoutSubviews() {
super.layoutSubviews()
containerView.dropShadow(color: .lightGray, opacity: 6, offSet: CGSize(width: 0, height: 0), radius: 6, scale: true)
}
Any help is very much appreciated.
I have made use of shadow in a view inside collectionview cell. Please see below link
View Sample
This is inside cellforItem
myCell.imgIcon.backgroundColor = UIColor.white
myCell.imgIcon.layer.shadowColor = UIColor.lightGray.cgColor
myCell.imgIcon.layer.shadowOpacity = 0.5
myCell.imgIcon.layer.shadowOffset = CGSize(width: 0, height: 0)
myCell.imgIcon.layer.shadowRadius = 5
I want to add shadow around collectionview cells. But the shadow is around the images and labels in the cell, and no shadow around the cell. Does someone know how to work it out?
cell.contentView.layer.cornerRadius = 2.0
cell.contentView.layer.borderWidth = 1.0
cell.contentView.layer.borderColor = UIColor.clear.cgColor
cell.contentView.layer.masksToBounds = true
cell.layer.masksToBounds = false
cell.layer.shadowColor = UIColor.black.cgColor
cell.layer.shadowOpacity = 0.5
cell.layer.shadowOffset = CGSize(width: -1, height: 1)
cell.layer.shadowRadius = 1
Shadow around the content(not the border)
You are applying shadow to contentView directly hence it is not working. You need to take a view inside your contentView, put all your content in this view and give some padding (e.g. 8pt) from all side.
Suppose I have named this view as vwContainer, then:
#IBOutlet weak var vwContainer: UIView!
let shadowPath = UIBezierPath(rect: vwContainer.bounds)
vwContainer.layer.masksToBounds = false
vwContainer.layer.shadowColor = UIColor.blackColor().CGColor
vwContainer.layer.shadowOffset = CGSizeMake(0.0, 5.0)
vwContainer.layer.shadowOpacity = 0.5
vwContainer.layer.shadowPath = shadowPath.CGPath
If you are trying to achieve any other UI than please update your question with image.
extension UIView {
func addShadow(color: UIColor, radius: CGFloat = 1, offset: CGSize) {
self.layoutIfNeeded()
self.layer.masksToBounds = false
self.layer.shadowColor = color.cgColor
self.layer.shadowOpacity = 0.5
self.layer.shadowOffset = offset
self.layer.shadowRadius = radius
self.layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
}
}
Use it as:
let offset = CGSize(width: -1, height: 1)
cell.addShadow(color: .black, offset: offset)
You need to set background color for the contentView as below
cell.contentView.backgroundColor = .white
I am using the following code:
bottomBorder.backgroundColor = UIColor.viewShadowGray().cgColor
bottomBorder.frame = CGRect(x: 0, y: view.frame.size.height - 1, width: view.frame.size.width, height: 1)
In extended UIColor file:
class func viewShadowGray() -> UIColor
{
return UIColor(red: 177.0/255.0, green: 177.0/255.0, blue: 179.0/255.0, alpha: 0.7)
}
changing the alpha value only makes the colour light, doesn't make it look blurred.
and getting :
I am expecting to obtain something as this:
How do I proceed rectifying this here?
edited , since you tried the shadow opacity thing in your new updated question i suggest using the implemented shadow properties for UIlayer
view.layer.masksToBounds = NO
view.layer.shadowOffset = CGSizeMake(-15, 20)
view.layer.shadowRadius = 5
view.layer.shadowOpacity = 0.5
view.layer.shadowColor = UIColor.black.cgColor
i would also recommend reading this article it would help you with that big time here
and check out this solution
extension UIView {
// OUTPUT 1
func dropShadow(scale: Bool = true) {
layer.masksToBounds = false
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.5
layer.shadowOffset = CGSize(width: -1, height: 1)
layer.shadowRadius = 1
layer.shadowPath = UIBezierPath(rect: bounds).cgPath
layer.shouldRasterize = true
layer.rasterizationScale = scale ? UIScreen.main.scale : 1
}
// OUTPUT 2
func dropShadow(color: UIColor, opacity: Float = 0.5, offSet: CGSize, radius: CGFloat = 1, scale: Bool = true) {
layer.masksToBounds = false
layer.shadowColor = color.cgColor
layer.shadowOpacity = opacity
layer.shadowOffset = offSet
layer.shadowRadius = radius
layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath
layer.shouldRasterize = true
layer.rasterizationScale = scale ? UIScreen.main.scale : 1
}
}
original answer here
using them like this
view.layer.dropShadow()
This question already has answers here:
UIView with rounded corners and drop shadow?
(35 answers)
Closed 4 years ago.
UIView Custom Class trigger only shadow. I want to display both shadow and rounded corner for specific edges.Here is my code. Any suggestions would be appreciated.
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
class CustomView: UIView {
override func layoutSubviews() {
self.shadowColor = UIColor.darkGray
self.shadowOffset = CGSize(width: 4, height: 4)
self.shadowOpacity = 0.5
self.shadowRadius = 6.0
//only rounded corners triggered in UI
self.backgroundColor = UIColor.white
self.roundCorners(corners: [.topRight, .bottomRight], radius: 15.0)
}
}
Thanks in advance
Use separate views for the shadow and the border. The base view is transparent and has the shadow. The border view clips any other subcontent that it has to its borders. See the code below.
// add the shadow to the base view
baseView.backgroundColor = UIColor.clear
baseView.layer.shadowColor = UIColor.black.cgColor
baseView.layer.shadowOffset = CGSize(width: 3, height: 3)
baseView.layer.shadowOpacity = 0.7
baseView.layer.shadowRadius = 4.0
// add the border to subview
let borderView = UIView()
borderView.frame = baseView.bounds
borderView.layer.cornerRadius = 10
borderView.layer.borderColor = UIColor.black.cgColor
borderView.layer.borderWidth = 1.0
borderView.layer.masksToBounds = true
baseView.addSubview(borderView)
// add any other subcontent that you want clipped
let otherSubContent = UIImageView()
otherSubContent.image = UIImage(named: "lion")
otherSubContent.frame = borderView.bounds
borderView.addSubview(otherSubContent)
Use this function:-
func addShadow(view: UIView, corner: CGFloat) {
view.layer.shadowColor = UIColor.gray.cgColor
view.layer.shadowOpacity = 0.5
view.layer.shadowRadius = 2
view.layer.shadowOffset = CGSize(width: 1, height: 1)
view.layer.masksToBounds = false
view.layer.cornerRadius = corner
}
Here's what I need to do to my two buttons.
and here's what I got right now.
What I'm doing:
- Set these up in IB inside a stackView.
- Add masks
- Add borders with width and color
- Add shadow.
The borders are being added but being cut-off as well by the masks.
Codes:
public func addCornerRadiusToCorners(
_ corners: UIRectCorner,
cornerRadius: CGFloat,
borderColor: UIColor,
borderWidth: CGFloat) {
// self.layer.masksToBounds = true
// self.clipsToBounds = true
self.layer.borderWidth = borderWidth
self.layer.borderColor = borderColor.cgColor
let size = CGSize(width: cornerRadius, height: cornerRadius)
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: size)
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
public func addDefaultShadow() {
let shadowPath = UIBezierPath(rect: self.bounds)
self.layer.masksToBounds = false
self.layer.shadowOffset = CGSize(width: 1, height: 1)
self.layer.shadowOpacity = 0.5
self.layer.shadowPath = shadowPath.cgPath
}
Any idea how to achieve the result in the first photo?
EDIT: the border is being cut, the result was just got from the UI Debugger of Xcode. Sorry.
Add corner radius to you view on viewDidAppear
#IBOutlet weak var segmentView: UIView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
segmentView.layer.cornerRadius = segmentView.frame.size.height/2;
segmentView.layer.borderWidth = 1.0;
segmentView.clipsToBounds = true
segmentView.layer.borderColor = UIColor.lightGray.cgColor
segmentView.layer.shadowColor = UIColor.black.cgColor
segmentView.layer.shadowOpacity = 0.2
segmentView.layer.shadowRadius = 10.0
segmentView.layer.shadowOffset = CGSize(width: 1, height: 1)
segmentView.layer.masksToBounds = false
}
Sample Output:
you forgot to clip ur view.
self.clipsToBounds = true
you need to set maskstobounds to the view layer
segmentView.layer.masksToBounds = true