Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView with rounded corners and drop shadow?

I’ve been working on an application for a couple of years and received a simple design request: Round the corners on a UIView and add a drop shadow.To do as given below.

I want a custom UIView... : I just wanted a blank white view with rounded corners and a light drop shadow (with no lighting effect). I can do each of those one by one but the usual clipToBounds/maskToBounds conflicts occur.

enter image description here

like image 735
Aditya Vaidyam Avatar asked Jan 21 '11 00:01

Aditya Vaidyam


People also ask

How do I add inner shadow to UIView with rounded corners?

Add subview with the same color which will be centered on the parent and will be with several pixels smaller. Like this you will have space from each side of the parent. On the parent turn on clipping subviews and add shadow to the inner view. Like this, you can have an inner shadow.

How do you round UIView corners?

If you start with a regular UIView it has square corners. You can give it round corners by changing the cornerRadius property of the view's layer . and smaller values give less rounded corners. Both clipsToBounds and masksToBounds are equivalent.


1 Answers

Swift

enter image description here

// corner radius blueView.layer.cornerRadius = 10  // border blueView.layer.borderWidth = 1.0 blueView.layer.borderColor = UIColor.black.cgColor  // shadow blueView.layer.shadowColor = UIColor.black.cgColor blueView.layer.shadowOffset = CGSize(width: 3, height: 3) blueView.layer.shadowOpacity = 0.7 blueView.layer.shadowRadius = 4.0 

Exploring the options

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Problem 1: Shadow gets clipped off

What if there are sublayers or subviews (like an image) whose content we want to clip to the bounds of our view?

enter image description here

We can accomplish this with

blueView.layer.masksToBounds = true 

(Alternatively, blueView.clipsToBounds = true gives the same result.)

enter image description here

But, oh no! The shadow was also clipped off because it's outside of the bounds! What to do? What to do?

Solution

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.

// 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) 

This gives the following result:

enter image description here

Problem 2: Poor performance

Adding rounded corners and shadows can be a performance hit. You can improve performance by using a predefined path for the shadow and also specifying that it be rasterized. The following code can be added to the example above.

baseView.layer.shadowPath = UIBezierPath(roundedRect: baseView.bounds, cornerRadius: 10).cgPath baseView.layer.shouldRasterize = true baseView.layer.rasterizationScale = UIScreen.main.scale 

See this post for more details. See here and here also.

This answer was tested with Swift 4 and Xcode 9.

like image 55
Suragch Avatar answered Oct 15 '22 07:10

Suragch