I'm having an issue when I attempt to add a drop shadow to an MKMapView's layer, in order for the shadow to be visible I have to set the view's clipsToBounds property to false. However, doing so causes the map tiles to draw outside the view's boundaries, overlapping the shadow and cutting of parts of my view. The result looks something like this:
I'm wondering if there's a way to draw a drop shadow without disabling bounds clipping or otherwise get the drop shadow to appear without this ugly visual bug. My code for setting the drop shadow looks like this:
self.mapView.layer.borderWidth = 5.0;
self.mapView.layer.borderColor = [[UIColor whiteColor] CGColor];
self.mapView.layer.shadowOffset = CGSizeMake(0.0, 0.0);
self.mapView.layer.shadowColor = [[UIColor blackColor] CGColor];
self.mapView.layer.shadowRadius = 5.0;
self.mapView.layer.shadowOpacity = 0.2;
self.mapView.clipsToBounds = NO;
Since the layer is owned by the MKMapView, it’s generally not a great idea to be touching it yourself. (This is the kind of thing that’s likely to break in weird ways in later OS versions, and behave in unpredictable ways (it’d be interesting to see if that even works at all with the new iOS 6 3D maps). With layer-backed views on OS X, you’re not supposed to touch the layer directly at all (unless it’s layer-hosting view, but that’s a different discussion))
To get a shadow underneath, just make your own new CALayer with a shadow positioned underneath the map. Alternatively nest the MKMapView as a subview of your own UIView, and add the shadow to your view (that has no need for clipping) instead.
You have to create two views, one for the shadow and an other for the rounded corners.
More info here : UIView Round Corners with Shadow
Related
I want to add a dropshadow to a button i've drawn in coregraphics. Other than making the button smaller than the frame, (which is messy coding as in future you'll forget about that and wonder why your button isn't the size it should be), what options do i have to draw the shadow? It's a custom shape, too.
The easiest way is to add it to you CALayer:
#include <QuartzCore/QuartzCore.h>
// iOS 4.0 or later
[self.layer setShadowColor:[[UIColor blackColor] CGColor]];
[self.layer setShadowOffset:CGSizeMake(1.0, 1.0)];
[self.layer setShadowOpacity:0.5];
[self.layer setShadowRadius:1.f];
If that won't work for you, let me know and I will post some code CG code.
Assuming I got the question correctly, you're looking for a way to stop clipping of the shadow. This is easy to achieve, assuming you have a view hierarchy in which the shadowed view resides, just turn off clipsToBounds on the superview of the shadowed view (and if needed on the superview's superview).
Be careful though, as there may've been other things your views were clipping and you didn't want to be seen (although normally this shouldn't be a problem).
I have a UIView set as "shadow", and I put this view behind a UIImageView to create a shadow effect. The only problem is, if you decrease the alpha of the image, you can see the white part of the UIView. How do I hide the whole UIView except for the shadow? Setting the backgroundColor to clearColor hides both the view and the shadow, which doesn't help. Thanks.
shadow.alpha = 0.95;
shadow.layer.cornerRadius = 10;
shadow.layer.shadowColor = [UIColor blackColor].CGColor;
shadow.layer.shadowOpacity = 1.0;
shadow.layer.shadowRadius = 10.0;
shadow.layer.shadowOffset = CGSizeMake(0, 4);
Have you tried modifying the UIImageView's layer to have the shadow, rather than having two views?
If that doesn't give the desired output, does a black UIView work? If you post a screenshot and the desired effect, maybe I can be of more assistance.
I don't think it's possible to do what you're attempting using the built-in shadow facilities. As you've discovered, there has to be something drawn in order for Quartz to have an outline to automatically shadow. (In this case, it's the background roundrect of the view.)
If you specify an explicit roundrect shadowPath for the shadow view's layer, that will do away with the need for the view to actually draw anything. However, the shadow itself appears to be constructed by filling the shadow path and then blurring and translating the resulting image, so you'll end up with essentially the same effect of a black background for the view.
I agree with Ryan Oksenhorn that you'd be better off working with the image view itself. If you add a shadow there, its opacity will drop with the view's, but that's probably all for the better. Do you really want to fade the image and leave a disembodied shadow behind?
How about you set
shadow.backgroundColor = [UIColor blackColor];
shadow.alpha = 1.0;
I have a UILabel with CALayer shadow on.And I just move it around via UIView animation.
The performance is poor and I can see the animation is not smooth at all.
I think it is the shadow of the UILabel which causes the animation problem because if I turn the shadow off, the animation becomes as smooth as normal.
I have tried using view.layer.shouldRasterize = YES;
But still the animation performance is there.
Anyone can give me some hints?
Thanks
You can greatly improve the performance of a CALayer’s shadow by using its shadowPath property—this allows it to draw the shadow without having to recalculate the alpha mask of the layer. For a rectangular view, you’d use it like this:
theView.layer.shadowPath = [UIBezierPath bezierPathWithRect:theView.bounds].CGPath;
or, if its corners are rounded,
theView.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:theView.bounds cornerRadius:theView.layer.cornerRadius].CGPath;
Note that this is a shadow around the view’s borders—if you want better performance on the shadow on the text itself, you either need to use the label’s text-shadow properties (which sacrifice the niceties of CALayer shadows, like blur, for better rendering speed) or—a much more complicated option—create a CGPathRef to use as the layer’s shadowPath from the text glyphs themselves.
Not sure if this is the answer you're looking for but I found this: Drop Shadow on UITextField text
It may be better performance, I haven't tried it but it seems it would be.
The UIActionSheet, when it has lots of items, is presented as a table with a border around it.
I'm trying to get a similar effect because I have a UIView with multiple UITableViews and I'd like to visually separate them. I'd like to use a border graphic that I specify.
Notice that with the UIActionSheet, the table actually sits inside the border and you see the table scroll underneath the rounded corners. You can see this in the Photos app if you view an image in landscape mode and hit the bottom-left hand corner button.
How do I get this same effect?
Edit: the "On This Day" by Sophiestication Software does something similar to what I want. The app uses a custom graphic that sits on top of a scrolling view so that the scrolling content appears to be underneath the image.
The simplest way is probably to add a border on the CALayer of the UITableView:
CALayer *layer = tableview.layer;
layer.borderWidth = 2;
layer.borderColor = [[UIColor redColor] CGColor];
layer.cornerRadius = 10;
layer.masksToBounds = YES;
Note that you need to include <QuartzCore/QuartzCore.h> and link with the QuartzCore framework.
layer.borderSize did not work for me layer.borderWidth did the trick.
i'm adding a shadow with
self.layer.cornerRadius = 6.0;
self.layer.shadowOffset = CGSizeMake(offset,offset);
self.layer.shadowOpacity = 0.7f;
self.layer.shadowRadius = 5.0;
where self(UIImageView based) has multiple layers whose contents are images.
Looks like when I add a shadow with the above code, individual layer gets a shadow of its own.
I wonder if it's possible to add a shadow to a view as a whole.
Besides, when I have many such image views with shadow, application slows down noticeably.
Wonder if taking out some property like cornerRadius would reduce the drawing computation time. (hard to track down in instruments)
Weird thing is, when the imageviews are on scrollviews, app doesn't get sluggish, but when they are placed on other view, app gets slowed down.
Thank you.