UITableView shadow top? - ios

I know there have been many questions on this before however none seem to work in my scenario. Pretty much I am trying to make the top maybe 10 points below the top of the frame of my tableview somewhat darker so have a nicer effect than just the cells scrolling off the frame.
Pretty much I need to accomplish an effect where the alpha starts at 0 and ends at 1 of a gray color which is 10 points high. This way there is some sort of subtle area before the top of the frame so that it doesn't look like the cells are just moving out of the frame.
Is this possible?
Thanks!

You can set a shadow to the navigationBar layer, assuming you are using one.
self.navigationController.navigationBar.layer.shadowColor = [[UIColor blackColor] CGColor];
self.navigationController.navigationBar.layer.shadowOffset = CGSizeMake(0.0f,0.0f);
self.navigationController.navigationBar.layer.shadowOpacity = 1.0f;
self.navigationController.navigationBar.layer.shadowRadius = 4.0f;
If you are not using a navigation controller, then you can apply this same type of shadow to a UIView's layer.

Related

Is it possible to add a transparent layer or view above a colored view?

I'm using AVFoundation framework to scan a barcode, but that may be unrelevant for my problem.
What I want:
I would like that the square bordered in green be transparent (not with the darkened black).
Here is what I have done:
I have 2 views: backgroundView( which occupies the whole screen) and highlightView which is the square bordered with green, on top of backgroundView (I have used a XIB for dimensions and positions) :
self.highlightView.layer.borderColor = [UIColor greenColor].CGColor;
self.highlightView.layer.borderWidth = 3;
// this following line does not allow the square to be transparent
self.highlightView.layer.opacity = 0;
// relative to AVFoundation
_previewLayer.frame = _backgroundView.bounds;
[_backgroundView.layer addSublayer:_previewLayer];
_previewLayer.backgroundColor = [UIColor blackColor].CGColor;
_previewLayer.opacity = 0.3;
UPDATE : xib (here representing the square with a clear color background), the backgroundView has the property black color background).
As I mentioned, you were looking in the wrong direction. There are multiple posts with a problem similar to yours, which have pretty decent answers. (You will have to study and understand to make the most of them):
Cut Out Shape with Animation
Simply mask a UIView with a rectangle
To sum it up, you need to apply the semi-transparent color to the layer of backgroundView and then play around with the layer's mask property to get the work done.
You can find many tutorials to learn using the layer and mask together.
Hope this helps.

iOS - how to create a "material design" compliant UIView with shadow?

I'm trying to see if there's a way to create a UIView with a shadow behavior compliant with material design. My understanding is that the shadow gets more intense as the object is further removed from the background surface.
I can manually add a shadow like this, however this shadow does not calculate how intense the shadow should be (based on Z order).
button.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:button.layer.bounds cornerRadius:11].CGPath;
button.layer.shadowOpacity = 1.0;
button.layer.shadowOffset = CGSizeMake(1,1);
button.layer.shadowColor = [UIColor blackColor].CGColor;
How do I create a UIView which will behave like Google's material design? I found this example, called Material Kit, however it simply hides shadow on touch
One way in which Google does this is by emphasizing the use of a
‘z-axis’ to create a sense of depth in which elements can occupy
different levels. In order to show that an element is occupying a
higher level on the z-axis, shadows are used around its border, being
cast on to the level below. What this creates is the illusion of an
interactive layer/element that exists above a different, lower
interactive layer/element.
You could subclass UIButton, and first set the shadow properties to your liking:
button.layer.shadowOffset = CGSizeMake(0, 1);
button.layer.shadowRadius = 5;
button.layer.shadowOpacity = 0;
Then change the shadowOpacity property when the highlighted state changes:
- (void)setHighlighted:(BOOL)highlighted
{
[super setHighlighted:highlighted];
self.layer.shadowOpacity = (highlighted ? 0.85 : 0);
}
In order to apply both a shadow and a rounded corner, you need to use 2 nested views. This is because the two effects require competing masksToBounds properties.
Nest 2 UIViews. Apply the shadow to the outer view, setting masksToBounds = false. Then apply the rounded corner to the inner view, which requires masksToBounds = true.
Note that, according to Apple docs, masksToBounds is equivalent to clipsToBounds.

UITextView Border on three sides

I'm currently styling a UITextView so that it looks like a text field using the following code:
//To make the border look very close to a UITextField
[_smsMessage.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]];
[_smsMessage.layer setBorderWidth:0.5];
//The rounded corner part
_smsMessage.layer.cornerRadius = 5;
_smsMessage.clipsToBounds = YES;
// Make append text view match
[_smsAppend.layer setBorderColor:[[[UIColor grayColor] colorWithAlphaComponent:0.5] CGColor]];
[_smsAppend.layer setBorderWidth:0.5];
//The rounded corner part
_smsAppend.layer.cornerRadius = 5;
_smsAppend.clipsToBounds = YES;
It puts a thin boarder around and then rounds the edges.
But what I would like to do is have this border for all sides apart from the bottom (so it would be the left, top and right sides that have the boarder, leaving the bottom exposed).
I'm unsure on how to implement this, does anyone have any ideas? - I have tried to research online, but I think the benefit of experience will come into play in this one.
I think that I will have to use some kind of sub-view (or a set of sub-views), can anyone advise?
I don't think there is any built-in support for this.
You could create a CAShapeLayer that's the same size as your view, and then add a CGPath to the layer. The path would be a combination of line segments and arc segments. If you look up how you construct a rounded rectangle you'll find an explanation of how to build one from line segments are arcs.
You could then add the the shape layer as a sub-layer of your view's content layer.
Instead of fiddling around with borders, create a 9 segment image and set it as the background.

iOS: drop shadow with sharp edges

I'm trying to add some shadows to one of my views and what I would like to achieve is drawing shadows only on one side and let them have sharp edges. No I've tried quite a few methods without any luck (using the shadow related properties of the view's CALayer + UIBezierPaths). However, iOS is always rendering a shadow with soft edges like this:
But what I really want to acchieve is something like this (without round corners and sharp edges on the sides except one):
Is there any elegant way to do this or will I have to draw the shadow myself using CoreGraphics?
PS: I forgot to mention, my view should actually be a custom UIButton, so overriding drawRect: would be a pain here
I've experienced a mask removing the shadow from view...so maybe you can try that.
CALayer *mask = [[[CALayer alloc] init] autorelease];
mask.backgroundColor = [UIColor blackColor].CGColor;
mask.frame = CGRectMake(0.0, 0.0, yellowView.bounds.size.width + shadowWidth, yellowView.bounds.size.height);
yellowView.layer.mask = mask;
I think what you want to be changing is the shadowRadius value - set that to zero and you should get the sharp edge you're looking for:
myView.layer.shadowRadius = 0;

Fill In UIView With Multiple Colors iOS

I'd like to fill in a UIView Background with multiple colors. I want to use it as a status bar of sorts, so if 1/2 the necessary steps are completed, the UIView Background will be 1/2 green and 1/2 red. When the user completes more steps (say 2/3), more of the UIView Background turns green (2/3 in this case).
I'm guessing I need to override
-(void) drawREct: (CGRect) rect
I imagine I would get the UIView, figure out how big it is, and divide it into 2 rectangles and then fill in those rectangles.
Another option would be to add 2 UIViews programmatically, but I'm a fan of IB.
Is it possible to divy up a UIView like I want?
Thanks
This is not an IB solution, but you can subclass UIView and override the drawRect method to add a custom gradient. This will allow you to put any number of colors you like and have them transition hard or smoothly. There are many nice tutorials online that should different ways to do this (some more elaborate, some quite simple).
Another option that is fairly simple, is to override drawRect, make the background red, then fill a rectangle that takes up the bottom half of the view. It doesn't allow for fancy or smooth transitions between colors, but it's very easy to implement. For instance, something along these lines should work:
-(void)drawRect:(CGRect)rect {
CGRect upperRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height * percentDone);
CGRect lowerRect = CGRectMake(rect.origin.x, rect.origin.y + (rect.size.height * percentDone), rect.size.width, rect.size.height *(1-percentDone));
[[UIColor redColor] set];
UIRectFill(upperRect);
[[UIColor greenColor] set];
UIRectFill(lowerRect);
}
Here percentDone is a float (declare, property(nonatomic), synthesize) that you can tie to the user's steps. Then just update the view when the user does something by
splitView.percentDone = .5;
[splitView setNeedsDisplay];
You can smooth this out with animations as well.
An easy way would be to set the background color for your background view to, say, red. Then add another view to that background view and call that the indicator view. Size and position the indicator view to cover the background, and set its background color to green. Connect the indicator view to an outlet in your view controller, and have the view controller adjust its width (or height) as necessary to correspond with the progress of the task at hand.
Another way would be as #PengOne suggests: create a custom view, give it a 'progress' property, and override -drawRect: to draw the contents appropriately. If you're going this route, there's nothing to stop you from getting a little creative. Instead of just filling two rectangles, make the boundary between the two colors a little more interesting. You could add ripples or bubbles that, with an appropriate sound effect, might look like a container filling with liquid. Or you could do a Qix-like animation that slowly fills the screen... ;-)

Resources