UIView with rounded corners and drop shadow?
The following code snippet adds a border, border radius, and drop shadow to v
, a UIView
:
// border radius
[v.layer setCornerRadius:30.0f];
// border
[v.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[v.layer setBorderWidth:1.5f];
// drop shadow
[v.layer setShadowColor:[UIColor blackColor].CGColor];
[v.layer setShadowOpacity:0.8];
[v.layer setShadowRadius:3.0];
[v.layer setShadowOffset:CGSizeMake(2.0, 2.0)];
Swift 5 Version :
// border radius
v.layer.cornerRadius = 30.0
// border
v.layer.borderColor = UIColor.lightGray.cgColor
v.layer.borderWidth = 1.5
// drop shadow
v.layer.shadowColor = UIColor.black.cgColor
v.layer.shadowOpacity = 0.8
v.layer.shadowRadius = 3.0
v.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
You can adjust the settings to suit your needs.
Also, add the QuartzCore framework to your project and:
#import <QuartzCore/QuartzCore.h>
See my other answer regarding masksToBounds
.
Note
This may not work in all cases. If you find that this method interferes with other drawing operations that you are performing, please see this answer.
How to round top two corners of UIView and add shadow above?
SWIFT 5: iOS 11 introduced maskedCorners
which results in smoother and better quality results. You can still use the UIRectCorner
in the function call and have it translated to CACornerMask
:
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
if #available(iOS 11.0, *) {
clipsToBounds = true
layer.cornerRadius = radius
layer.maskedCorners = CACornerMask(rawValue: corners.rawValue)
} else {
let path = UIBezierPath(
roundedRect: bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius)
)
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
func addShadow(shadowColor: CGColor = UIColor.label.cgColor,
shadowOffset: CGSize = CGSize(width: 1.0, height: 2.0),
shadowOpacity: Float = 0.4,
shadowRadius: CGFloat = 3.0) {
self.layer.shadowColor = shadowColor
self.layer.shadowOffset = shadowOffset
self.layer.shadowOpacity = shadowOpacity
self.layer.shadowRadius = shadowRadius
self.layer.masksToBounds = false
}
}
These functions need to be applied in layoutSubviews() of your superview.
override func layoutSubviews() {
roundCorners([.topLeft, .topRight], radius: 15)
addShadow(shadowColor: UIColor.text1.cgColor, shadowOffset: CGSize(width: 0, height: -3), shadowOpacity: 0.2, shadowRadius: 5)
}
Creating a shadow for a UIImageView that has rounded corners?
If you set clipsToBounds
to true
, this will round the corners but prevent the shadow from appearing. In order to resolve this, you can create two views. The container view should have the shadow, and its subview should have the rounded corners.
The container view has clipsToBounds
set to false
, and has the shadow properties applied. If you want the shadow to be rounded as well, use the UIBezierPath
constructor that takes in a roundedRect
and cornerRadius
.
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
outerView.clipsToBounds = false
outerView.layer.shadowColor = UIColor.black.cgColor
outerView.layer.shadowOpacity = 1
outerView.layer.shadowOffset = CGSize.zero
outerView.layer.shadowRadius = 10
outerView.layer.shadowPath = UIBezierPath(roundedRect: outerView.bounds, cornerRadius: 10).cgPath
Next, set the image view (or any other type of UIView
) to be the same size of the container view, set clipsToBounds
to true
, and give it a cornerRadius
.
let myImage = UIImageView(frame: outerView.bounds)
myImage.clipsToBounds = true
myImage.layer.cornerRadius = 10
Finally, remember to make the image view a subview of the container view.
outerView.addSubview(myImage)
The result should look something like this:
rounded edges with a shadow
Add dummy container view and assign it the shadow, after that put inside of it the image view like this:
Declare your objects under your class controller:
let imgV = UIImageView()
let dummyView = UIView()
after that in viewdidLoad set property and constraints:
imgV.image = UIImage(named: "yourImage")
imgV.contentMode = .scaleToFill
imgV.layer.cornerRadius = 20
imgV.clipsToBounds = true
imgV.translatesAutoresizingMaskIntoConstraints = false
dummyView.center = self.view.center
dummyView.backgroundColor = UIColor.yellow
dummyView.layer.shadowColor = UIColor.gray.cgColor
dummyView.layer.shadowOpacity = 1
dummyView.layer.shadowOffset = CGSize(width: 2, height: 2)
dummyView.layer.shadowRadius = 5
dummyView.layer.cornerRadius = 20
dummyView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(dummyView)
dummyView.heightAnchor.constraint(equalToConstant: 200).isActive = true
dummyView.widthAnchor.constraint(equalToConstant: 200).isActive = true
dummyView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
dummyView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
dummyView.addSubview(imgV)
imgV.topAnchor.constraint(equalTo: dummyView.topAnchor).isActive = true
imgV.bottomAnchor.constraint(equalTo: dummyView.bottomAnchor).isActive = true
imgV.leadingAnchor.constraint(equalTo: dummyView.leadingAnchor).isActive = true
imgV.trailingAnchor.constraint(equalTo: dummyView.trailingAnchor).isActive = true
this is the result
Swift - Problems with corner radius and drop shadow
The following Swift 5 / iOS 12 code shows how to set a subclass of UIButton
that allows to create instances with rounded corners and shadow around it:
import UIKit
final class CustomButton: UIButton {
private var shadowLayer: CAShapeLayer!
override func layoutSubviews() {
super.layoutSubviews()
if shadowLayer == nil {
shadowLayer = CAShapeLayer()
shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 12).cgPath
shadowLayer.fillColor = UIColor.white.cgColor
shadowLayer.shadowColor = UIColor.darkGray.cgColor
shadowLayer.shadowPath = shadowLayer.path
shadowLayer.shadowOffset = CGSize(width: 2.0, height: 2.0)
shadowLayer.shadowOpacity = 0.8
shadowLayer.shadowRadius = 2
layer.insertSublayer(shadowLayer, at: 0)
//layer.insertSublayer(shadowLayer, below: nil) // also works
}
}
}
According to your needs, you may add a UIButton
in your Storyboard and set its class to CustomButton
or you may create an instance of CustomButton
programmatically. The following UIViewController
implementation shows how to create and use a CustomButton
instance programmatically:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = CustomButton(type: .system)
button.setTitle("Button", for: .normal)
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
let widthConstraint = button.widthAnchor.constraint(equalToConstant: 100)
let heightConstraint = button.heightAnchor.constraint(equalToConstant: 100)
NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
}
The previous code produces the image below in the iPhone simulator:
How to add inner shadow to UIView with rounded corners
It's a trick. You give shadow and border to same view, the shadow will fall inside the view. please make sure the background color of view is clear. use the below code for reference.
yourView.layer.shadowColor = UIColor.gray.cgColor
yourView.layer.shadowOpacity = 0.3
yourView.layer.shadowOffset = CGSize.zero
yourView.layer.shadowRadius = 6
yourView.layer.masksToBounds = true
yourView.layer.borderWidth = 1.5
yourView.layer.borderColor = UIColor.white.cgColor
yourView.layer.cornerRadius = imageView.bounds.width / 2
Related Topics
Delete Image from Photo Gallery
Avcapturevideopreviewlayer Add Overlays and Capture Photo in iOS
Swift - Update/Refresh Label That Displays Time
iOS Mkmapview Custom Images Display on Top Left Corner
Why Swift Use a Struct as Dictionary Key Instead of a String Here
Problems with Cropping a Uiimage in Swift
Wkwebview Decidepolicyfornavigationaction Being Call After the Long Press Recogniser Ended
How to Catch Nsunknownkeyexception in Swift 2.2
Apply Nspredicate on [(String, Array<String>)]
Uitraitcollection Clarification
Sorting Struct Array in Swift 4
How to Change How a Remote Notification Is Presented Before Presentation
Disable Long Press Back Button (Callout Menu)
Adding a Target to a Button Programmatically Throws an Error "Unrecognized Selector Sent to Class"
Dynamic Uitablecellview Height
What Is the Simplest Way to Retrieve the Device Serial Number of an iOS Device Using Monotouch