I have to create a custom UIView
that will have round corners, a border, a shadow and its drawRect()
method is overridden to provide custom drawing code with which several straight lines are drawn into the view (I need to use a fast, lightweight approach here since many of these views may be rendered).
The problem I'm currently facing is that the shadow doesn't apply anymore to the round corners as soon as I override drawRect()
in the view class (even without any custom code yet in it). See the attached image for the difference:
In the view controller I'm using the following code:
view.layer.cornerRadius = 10;
view.layer.masksToBounds = true;
view.layer.borderColor = UIColor.grayColor().CGColor;
view.layer.borderWidth = 0.5;
view.layer.contentsScale = UIScreen.mainScreen().scale;
view.layer.shadowColor = UIColor.blackColor().CGColor;
view.layer.shadowOffset = CGSizeZero;
view.layer.shadowRadius = 5.0;
view.layer.shadowOpacity = 0.5;
view.layer.masksToBounds = false;
view.clipsToBounds = false;
In the overridden drawContext()
I would use something like:
var context:CGContext = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor);
// Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(context, 2.0);
CGContextMoveToPoint(context, 0.0, 0.0); //start at this point
CGContextAddLineToPoint(context, 20.0, 20.0); //draw to this point
CGContextStrokePath(context);
But as said above, the shadow problem occurs even without this code added.
Is there any other/better way to draw lightweight elements onto a view other than this approach that is compatible with round corners and shadows? I don't want to add any unnecessary extra views or image contexts to the view since these need to be light and performant.
Swift 3
I made an UIView extension and its basically the same idea suggested by Mundi:
Use:
In addition to the Frederic Adda's solution, don't forget to position the view that has shadow with a padding to the superview, where the shadow can be drawn. Otherwise the shadow will be clipped off. I made this mistake in my custom cell, and thought the solution was wrong until I added a padding of 8px all around.
I use this extension to
UIView
:Shadow is dropped from whatever is inside view's layer. When you disable clipping, entire layer rectangle gets filled with default
backgroundColor
so the shadow becomes rectangular too. Instead of clipping it with rounded mask just make layer's contents rounded, draw them yourself. Andlayer
's border is drawn around its bounds, so you need to draw it yourself too.For example, in
backgroundColor
setter set actual background color toclearColor
and use passed color indrawRect
to draw a rounded rect with.In example below I declare properties as
IBInspectable
and the whole class asIBDesignable
, so everything can be set in storyboard. This way you can even use default Background selector to change your rounded rect color.Swift
Swift 3
Objective-C .h
Objective-C .m
Result
Try this it is work for me...
This is my solution. If you have multiple type of views like UIView, UIControl, UITableView and so on, and don't want to make subclasses of each of them, or you want to add this effect with smallest changes to your code, then this might be what you are looking for.
Objective-C.h
Objective-C.m