Creating a shadow view - iphone

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;

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

UITableView Stacked/Shadow Background

I'm trying to make a UITableView look as though it's on top of a stack of papers. I did a similar version of this using UIView by overriding drawRect, but with UITableView's complexity, I believe it will be more involved than it was with a standard UIView. If I use a stretchable image, the stretched bits won't line up. What would be the best way of achieving something like this?
For Shadow, you can use the CALayer, as in the example below.
tableView.layer.shadowRadius = 3.f;
tableView.layer.shadowColor = [UIColor blackColor].CGColor;
tableView.layer.shadowOffset = CGSizeMake(2, 2);
tableView.layer.shadowOpacity = .6f;
For the stack impression, i would add some views with same shadow borders beneath the table view.

Stretching a portion of a UIView using contentStretch

I need some help understanding the use of the contentStretch property on a UIView. I'd appreciate 1) some guidance on how to achieve the effect I'm going for and 2) a reference to any comprehensive documentation that exists on how to use this property. While I thought I understood the Apple documentation, I now see that I don't. Here is what I'm trying to do.
I have a custom UIView that renders a view that looks like figure a. below. The drawRect method of this UIView paints the inner box on the left (with the rounded corners and white background) with a different color and affect than is used for the rest of the view. Also, the 4 corners of the UIView are not stretchable (this would result in distortion) so I need to stretch only the center of the UIView background.
I want to grow this view to a shape similar to that pictured in figure b. below. In doing so I want only the portion of the view outside the white box (or to the right of the white box) to be stretched/repeated as I increase the UIView's height.
In all of my attempts I have only been able to produce a strecth that affects the entire width of the view and results in a view similar to figure c.
Is it possible for me to achieve the effect that I want (figure b.) using contentStretch? Is there some other technique I should be using short of re-drawing the entire view, or is re-drawing the only (or best) way to go about this?
Thanks,
To make this happen with contentStretch, you would have to set the contentStretch rectangle so that its top edge is below the bottom edge of the white box, and so that its left edge is to the right of the right edge of the white box. You will probably find that your background pattern gets stretched too much and looks ugly.
Instead, give your view a subview that draws just the white box. Set the subview's springs and struts so that the box stays at the upper left and doesn't stretch.
I would make the white box stretchable on top, and a background view filled with a pattern using colorWithPatternImage:
patternView.backgroundColor = [UIColor colorWithPatternImage:#"myBackgroundPattern.png"];
and the black stroke could be done with:
#include <QuartzCore/QuartzCore.h>
...
patternView.layer.borderWidth = 2.f;
patternView.layer.borderColor = [[UIColor blackColor] CGColor];
What you are trying to achieve can be done using the resizableImageWithCapInsets method of a UIImage. This way, you can set cap widths on each side of the image and specify which part of the image needs to be repeated (not stretched).
An UIEdgeInset is a struct consisting of four components as follows (CGFloat topCapWith, CGFloat leftCapWith, CGFloat bottomCapWith, CGFloat rightCapWith)
The code below would do the trick
UIImage * backgroundImage = [[UIImage imageNamed:#"Stretch.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(80, 4, 4, 10)];
backgroundImageView.image = backgroundImage;
Since content stretch is deprecated, best approach is to use auto layout. In the inner rectangle give a defining height and width constant and bind its top and leading constraints to the parent view.
In order to get a bottom growth in outer rectangle, bind its bottom constraint or alternatively you can also chnage it height.

UITapGestureRecognizer on transparent view

I have a tree with views where the highest level view is transparent and contains either an image or a label (with a transparent background).
When attaching a UITapGestureRecognizer to this view, I only get notifications on the views which contain images.Also, if I leave the view empty, then I get events only when the background color is different than [UIColor clearColor].
I have done a dump and the entire view tree has userInteractionEnable = YES.
How can I get the UITapGesturerRecognizer to work on the view with a transparent background?
Solved
Problem was not what I thought. The transparent views were in a scroll view and during initialization they were outside of the view's visible area. Those within the visible area work ok.
Wild guesses here, but if you include a 1x1 pixel image in the view, would that view then qualify for gestures?
Another equally wild guess would be to add a transparent image to the view and try that.
Try giving the view a nearly-transparent background color, like [UIColor colorWithWhite:0 alpha:0.01].
Try setting the background color to whatever except the clearColor and setting the alpha property to 0.0;
myView.backgroundColor = [UIColor blackColor];
myView.alpha = 0.0;

Putting UIView with alpha 1 on top of UIView with alpha 0.5

I'm trying to have a modular uiview that will be placed on top of another view. The modular view has an alpha value of 0.5, and appears in the middle of the main view.
Now, I would like for text to be rendered on that modular UIView. However, whenever I:
[modularView addSubview:text]
it looks all hazy.
How can I make the text tack sharp, but keep the alpha of its parent view at 0.5?
Thanks!
Set the alpha for the background color rather than for the whole view:
[modularView setBackgroundColor:[UIColor colorWithRed:0.0
green:0.0
blue:0.0
alpha:0.5]];
This will allow any subviews to retain full opacity. The color in my code is black. Just set the RGB values for whatever color you're wanting.
You could also just use a UILabel instead of a UIView and set it's background the same way. Then you don't need to add a subview--though I'm not sure what else you have in your modularView view.
I'm doing the same on a project i'm working on, my "modalview" is on top of a fullscreen image.
My "modalview" has alpha 1.0 and the background color is black with 50% opacity.
Then the text is white, with default highlight and a dark shadow with 1.0 h and v-offset.
Hope it helps...
PS: make sure you're adding the text in front of the "modalview", not behind it ;)