(iphone) add shadow to uiview as a whole which has multiple layers - iphone

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.

Related

How to add a drop shadow to an MKMapView without disabling clipsToBounds

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

Creating a shadow view

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;

UIView: Rounded Corners Without Performance Issues

I am using an AQGridView to display my data in a grid on iPad. Every cell is a UIView subclass and typically, there are 18 cells displayed simultaneously.
I would like to add a round corner to these cells, so I set the cornerRadius property of the relevant layers (i.e. the layer of the main UIView and of one subview). However, this results in performance issues and the scrolling is not smooth any more. When using other CALayer properties, such as shadowOpacity, this does not happen.
Are there any other ways to add a rounded corner (apart from using an image)? Or am I doing something wrong?
I also saw a major performance hit when using cornerRadius on the layer of a view that contained a UIImageView subview. Rasterization solved that problem: view.layer.shouldRasterize = YES;
It could be where you're placing the setCornerRadius call. Make sure it's somewhere that only gets called once, not, for example, in a drawRect method.

Iphone sdk, Rounded UIImageView FRAME corners, not just masking it

i am building a app in which if a UIImageView hits another something happens, i am using the CGRectIntersetsRect statement, i would like to make it as accurate as i can, at the moment i have about 8 UIImageViews inside this one UIImageView and i am detecting if something hits them 8 little views, i have decided that this is not a very accurate way to go about it. The problem is that the UIImageView the other UIImageView's are in, Its a Oval, so it is complicated, i have tryed masking it, using the
image.layer.radius 10.0 or whatever the code is.
but this doesnt actually transform the whole frame, is there any way to actually transform the whole frame so when a UIImageView hits the Oval shape then something happens?
if so could someone explain it to me.
Thanks
Harry
this is really simple indeed. As a View, UIImageView has a layer and a layer has cornerRadius properties:
imageView.layer.cornerRadius = 5.0;
imageView.layer.masksToBounds = YES;
eBuildy, iPhone specialists
A UIImageView's frame is a CGRect, a CGRect is a rectangle and a rectangle has no rounded properties.

CATiledLayer blanking tiles before drawing contents

All,
I'm having trouble getting behavior that I want from CATiledLayer. Is there a way that I can trigger the tiles to redraw without having the side-effect that their areas are cleared to white first? I've already subclassed CATiledLayer to set fadeDuration to return 0.
To be more specific, here are the details of what I'm seeing and what I'm trying to achieve:
I have a UIScrollView with a big content size...~12000x800. Its content view is a UIView backed by a CATiledLayer.
The UIView is rendered with a lot of custom-drawn lines
Everything works fine, but the contents of the UIView sometimes change. When that happens, I'd like to redraw the tiles as seamlessly as possible. When I use setNeedsDisplay on the view, the tiles redraw but they are first cleared to white and there's a fraction-of-a-second delay before the new content is drawn. I've already subclassed CATiledLayer so that fadeDuration is set to 0.
The behavior that I want seems like it should be possible...when you zoom in on the scrollview and the content gets redrawn at a higher resolution, there's no blanking before the redraw; the new content is drawn right on top of the old one. That's what I'm looking for.
Thanks; I appreciate your ideas.
Update:
Just to follow up - I realized that the tiles weren't being cleared to white before the redraw, they're being taken out entirely; the white that I was seeing is the color of the view that's beneath my CATiledLayer-backed view.
As a quick hack/fix, I put a UIImageView beneath the UIScrollView, and before triggering a redraw of the CATiledLayer-backed view I render its visible section into the UIImageView and let it show. This smooths out the redraw significantly.
If anyone has a better solution, like keeping the redraw-targeted tiles from going away before being redrawn in the first place, I'd still love to hear it.
I've found that if you set levelsOfDetailBias and levelsOfDetail both to the same value (2 in my case), then it only redraws the tiles that are touched by my setNeedsDisplayInRect: call, as you'd hope.
However if the levelsOfDetail is different to LODB, then any calls to setNeedsDisplayInRect: redraw all the tiles.
You could add another layer (possibly a CATiledLayer) behind the existing tiled layer. (Sort of a double-buffered solution.) You would call setNeedsDisplay: on the second layer from a timer that fires after a few seconds to ensure that that layer doesn't redraw at the same time as the front layer.
Another potential option is to use the same delegate to draw content to a bitmap context and swap the bitmap into the backing store once the content is refreshed. This should produce a flicker-free result. That being said, I can't tell you how this might be done, and one nice thing about CATiledLayers is they automatically generate tiles when you zoom and pregenerate tiles when you pan once zoomed in.
I would like to see how you implement your application. I have been looking for weeks to find an example that uses a combination of UIScrollView and a CATiledLayer-back view with a lot of custom drawn lines. Apple has some great sample code - but it all involves images rather than line art, so no help for me.
Having read through these answers without a solution, I discovered that tiling a page was the dominant background task.
Preparing my lo-res placeholder image on a high priority queue solved this issue - the images now appear while the tiling is occurring. Caching the placeholder images further improves their appearance - they appear before the tiling begins.
With newer devices, the tiling it so fast, these tricks might not matter. A sample PDF consisting of large scanned images (e.g. a scanned book) tiles the slowest in my experience, and makes for good test data.
I had the same problem with iPad.
The solution was more simple than I thought and far more simple than using UIImageView to render display before redrawing... :
Just don't set any background color for the Layer!
I had CATiledLayer set in a similar way:
layer = [[CATiledLayer alloc] init];
layer.masksToBounds = YES;
layer.contentsGravity = kCAGravityLeft;
//layer.backgroundColor = [[UIColor whiteColor] CGColor];
layer.tileSize = CGSizeMake(1004.0, 1004.0);
layer.levelsOfDetail = 16;
layer.levelsOfDetailBias = 8;
Note that I have commented out the line setting layer's background color to white.
After that the white blank before redraw problem disappeared!
Let me know if anyone has tried that.