Convert CSS Box Shadow to iOS Shadow - ios

Does anyone know how I can convert a box-shadow to a shadow on a UIButton in Objective-C?
For example this shadow:
box-shadow: 2px 0 0 0 #46d466,-2px 0 0 0 #46d466,0 2px 4px 0 rgba(0,0,0,.1),0 2px 8px 0 rgba(70,212,102,.7);

UIButton have a special property layer of type CALayer.The layer property is great for many quick special effects, some built-in, like shadows are one of those built-in effects.
Please find the below code.
btn.layer.shadowColor = [UIColor grayColor].CGColor;
btn.layer.shadowOffset = CGSizeMake(3.0, 3.0);
btn.layer.shadowOpacity = 2.0;
btn.layer.shadowRadius = 2.0;
shadowOffset : The blur radius used to create the shadow. Defaults
to (0, -3).
shadowOpacity : The opacity of the layer’s shadow. Defaults to 0.
shadowRadius : The blur radius (in points) used to render the
layer’s shadow.
For more information please review the API on developer site.
Or also you can change the offset of shadow.
btn.layer.shadowOffset = CGSizeMake(10.0, 10.0);
You can also change the radius of the shadow which affects how blurry the shadow appears.
btn.layer.shadowRadius = 10.0;
Hope it will work for you!!!

CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = CGRectMake( 0, 0, 5, testBtn.frame.size.height);
gradient.colors = [NSArray arrayWithObjects:(id)[UIColor clearColor].CGColor, (id)[UIColor colorWithRed:0 green:0 blue:0 alpha:0.8f].CGColor, nil];
[testBtn.layer insertSublayer:gradient atIndex:0];
you can give whatever color or gradient.
hope this helps.
or
CALayer * bgLayer = [CALayer layer];
bgLayer.frame = CGRectMake( 0, 0, 5, testBtn.frame.size.height);
bgLayer.backgroundColor = [UIColor grayColor].CGColor;
[testBtn.layer insertSublayer: bgLayer atIndex:0];

You need to use the button layer property. You can only assign one colour though (or use a gradient as suggested above) e.g.
button.layer.shadowColor = [UIColor grayColor].CGColor;
button.layer.shadowOffset = CGSizeMake(0, 1.0);
button.layer.shadowOpacity = 1.0;
button.layer.shadowRadius = 0.0;

Related

How to do colour shading in Objective-C

I need to do a colour shading in objective c. As shown in this image shade is on the button of HardService and SoftService.
Is there is any way to do this ? Thanks in Advance!
CAGradientLayer would server your purpose - Reference:
http://blog.apoorvmote.com/gradient-background-uiview-ios-swift/
You can use either a gradient image or CAGradientLayer for this purpose
CAGradientLayer added to an existing button:
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = button.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor blackColor] CGColor], nil];
[button.layer insertSublayer:gradient atIndex:0];
You can use an image for showing shadow. Use blur image or change alpha of the imageview.
Or if you want to do it programmatically, try it:
Obj c:
//create elliptical shadow for button through UIBezierPath
CGRect ovalRect = button.bounds;
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:ovalRect];
//applying shadow to path
button.layer.shadowColor = [UIColor yourcolor].CGColor;
button.layer.shadowOffset = CGSizeMake(0.0, 0.0);
button.layer.shadowOpacity = 1.0;
button.layer.shadowRadius = 3.0;
button.layer.shadowPath = path.CGPath;
Swift :
//create elliptical shdow forimage through UIBezierPath
var ovalRect = button.bounds
var path = UIBezierPath(ovalInRect: ovalRect)
//applying shadow to path
button.layer.shadowColor = UIColor(white: 0.0, alpha: 0.5).CGColor
button.layer.shadowOffset = CGSizeMake(0.0, 0.0)
button.layer.shadowOpacity = 1.0
button.layer.shadowRadius = 3.0
button.layer.shadowPath = path.CGPath
Taken from http://www.innofied.com/implementing-shadow-ios/ and also have a look to know more: UIView with rounded corners and drop shadow?
My another answer related to this: Drop shadow in ios

How to draw an outline around a column?

I would like to draw an outline around a column. here is how my app actually looks like: https://gyazo.com/80dffe6a153e82565a610222a43e0c11
So the white column represent the day on where we are actually. But I don't really want to do that.
Actually I'm doing this:
if(column == _intOfTheDay){ //intOfTheDay represent the day one where we are actually
cell.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0.95];
}
I've tried something like this to get closer of the result that I want:
if(column == _intOfTheDay){
cell.layer.borderWidth = 5.0f;
cell.layer.borderColor = [UIColor redColor].CGColor;
}
But the problem here (without all the bugs due to the UICollectionView) is that it draw a rectangle around each cell. And what I would like is to draw only one rectangle but around all the column.
How could I process?
Every help will be appreciated, thanks in advance.
If you don't want to subclass the UICollectionViewCell then use this :
float borderWidth = 5.0;
CALayer *leftBorder = [CALayer new];
leftBorder.frame = CGRectMake(0.0, 0.0, borderWidth, cell.frame.size.height);
leftBorder.backgroundColor = [UIColor redColor].CGColor;
[cell.layer addSublayer:leftBorder];
CALayer *rightBorder = [CALayer new];
rightBorder.frame = CGRectMake(cell.frame.size.width - borderWidth, 0.0, borderWidth, cell.frame.size.height);
rightBorder.backgroundColor = [UIColor redColor].CGColor;
[cell.layer addSublayer:rightBorder];
You can do something like this, set three border to first cell of column- left,right and top and for last cell of column left,right and bottom and for all middle cell left and right. you can use CALayer to set one side border like below example,
CALayer *TopBorder = [CALayer layer];
TopBorder.frame = CGRectMake(0.0f, 0.0f, self.myImageView.frame.size.width, 3.0f);
TopBorder.backgroundColor = [UIColor redColor].CGColor;
[cell.layer addSublayer:TopBorder];

How to create a gradient perimeter using CALayer

I've been trying for some time now, using CAGradientLayer to produce this .
Initially I tried having a gradient background using the .colors property, however this is only a background fill. Trying this approach, I tried to add another CALayer inside that had a black background, however i could never get the radius correct, and it would create a line of various thickness at the rounded corners.
Is there a better way to create this rounded rect border with a gradient to it? Will CALayer not achieve this and should I move over to UIBezierPath or CGContextRef?
Code for failed attempt:
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(12*twelthWidth - squareCentre.x - squareSize.width, squareCentre.y, squareSize.width, squareSize.height)];
// Create the rounded layer, and mask it using the rounded mask layer
CAGradientLayer *roundedLayer = [CAGradientLayer layer];
[roundedLayer setFrame:view.bounds];
roundedLayer.cornerRadius = view.bounds.size.width/5;
roundedLayer.masksToBounds = YES;
roundedLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor redColor] CGColor], (id)[[UIColor blueColor] CGColor], nil];
roundedLayer.borderWidth = 4;
roundedLayer.borderColor = [UIColor clearColor].CGColor;
// Add these two layers as sublayers to the view
int BorderWidth = 5;
CALayer *solidColour = [CALayer layer];
solidColour.cornerRadius = view.bounds.size.width/5;
solidColour.masksToBounds = YES;
solidColour.backgroundColor = [UIColor blackColor].CGColor;
[solidColour setFrame:CGRectMake(BorderWidth, BorderWidth, roundedLayer.bounds.size.width - 2*BorderWidth, roundedLayer.bounds.size.height - 2*BorderWidth)];
[view.layer insertSublayer:roundedLayer atIndex:0];
[view.layer insertSublayer:solidColour above:roundedLayer];
[self.view addSubview:view];
Which produces:
Whereby the corners aren't right. Could it be that I need to calculate a different radius for the second layer?
Edit
After setting the radius of the solid colour to solidColour.bounds.size.width/5, it still isn't right - It goes too thin at the corners.
The problem you are seeing is because the inner and outer corner radius are the same. That is what causes the line thickness to vary. This illustration from CSS-Tricks highlights the issue (even thought you aren't using CSS, the problem is still the same):
The solution is to calculate the inner radius as:
innerRadis = outerRadius - lineThickness
As shown in this illustration by Joshua Hibbert:
Instead of using the view bounds to set the cornerRadius of the solid layer, use the layer's frame value after you've set it to the correct inset value:
solidColour.masksToBounds = YES;
solidColour.backgroundColor = [UIColor blackColor].CGColor;
[solidColour setFrame:CGRectMake(BorderWidth, BorderWidth, roundedLayer.bounds.size.width - 2*BorderWidth, roundedLayer.bounds.size.height - 2*BorderWidth)];
solidColour.cornerRadius = solidColour.frame.size.width/5;
[view.layer insertSublayer:roundedLayer atIndex:0];
[view.layer insertSublayer:solidColour above:roundedLayer];
With this I get the following image
Just for your convenience if you use swift
let v = yourUIVIEW
let outerRadius:CGFloat = 60
let borderWidth:CGFloat = 8;
let roundedLayer = CAGradientLayer()
roundedLayer.frame = v.bounds
roundedLayer.cornerRadius = outerRadius
roundedLayer.masksToBounds = true
roundedLayer.endPoint = CGPoint(x: 1 , y: 0.5)
roundedLayer.colors = [ UIColor.redColor().CGColor, UIColor.blueColor()!.CGColor]
let innerRadius = outerRadius - borderWidth
//Solid layer
let solidLayer = CALayer()
solidLayer.masksToBounds = true
solidLayer.backgroundColor = UIColor.whiteColor().CGColor
solidLayer.cornerRadius = innerRadius
solidLayer.frame = CGRect(x: borderWidth, y: borderWidth, width: roundedLayer.bounds.width - 2*borderWidth, height:roundedLayer.bounds.height - 2*borderWidth )
v.layer.insertSublayer(roundedLayer, atIndex: 0)
v.layer.insertSublayer(solidLayer, above: roundedLayer)

Glossy Label Look in iOS

I am looking at how to make a label appear to have a rounded glossy look, similar to this:
I know I can use the CALayer in the app for different things like borders, and rounded corners, but I'm unsure about a glossy look. Right now I am using:
CALayer* l = [myCounterLabel layer];
CALayer* m = [myhiddenlabel layer];
[l setMasksToBounds:YES];
[l setCornerRadius:11];
[l setBorderWidth:2.0];
[l setBorderColor:[[UIColor blackColor] CGColor]];
This gives me a label that looks like this (I know font and everything else doesn't match...right now just looking for a glossy look:
There's a few ways you could do this but a CAGradientLayer is likely your best bet. Assume you have CAGradientLayer* property:
self.gradient = [CAGradientLayer layer];
self.gradient.frame = CGRectMake(100, 100, 100, 100);
self.gradient.cornerRadius = 11;
self.gradient.borderWidth = 2.0;
// Set the colors you want in the gradient
self.gradient.colors = #[(id)[UIColor grayColor].CGColor, (id)[UIColor grayColor].CGColor, (id)[UIColor blackColor].CGColor, (id)[UIColor blackColor].CGColor];
// if you want to control as to the distribution of the gradient you can set the control points for the gradient here (make sure you have as many as you have colors)
self.gradient.locations = #[#0.0f, #0.5f, #0.5f, #1.0f];
You could try to add another sub-layer to your original layer with background color to fill the second half part:
CALayer *sublayer = [CALayer layer];
sublayer.backgroundColor = [UIColor blueColor].CGColor; //your color
sublayer.frame = CGRectMake(0, 50, 50, 50); //parent layer (height 100, width 50)
[yourLayer addSublayer:sublayer];

text with sharp shadow around

I want to achieve the text appearance like in the pictures below:
Now I'm working on shadow around the letters and I can't figure out how to do that.
What I've tried so far:
- The solution with:
label.shadowColor = [UIColor blackColor];
label.shadowOffset = CGSizeMake(1, 2);
gives a nice sharp shadow, but it doesn't fit my needs by two reasons:
It gives a shadow only from one side, set up by shadowOffset, whereas I need a "wrapping" shadow;
This solution doesn't give the soft part of the shadow (gradient) as there is in the pictures;
-The solution with:
label.layer.shadowOffset = CGSizeMake(0, 0);
label.layer.shadowRadius = 5.0;
label.layer.shouldRasterize = YES;
label.layer.shadowOpacity = 1;
label.layer.shadowColor = [UIColor blackColor].CGColor;
label.layer.masksToBounds = NO;
Works great, but it gives too soft shadow even though the shadowOpacity is set to 1 and the shadowColor is set to black:
Obviously it's not enough and I already think about drawing in labels' context. But it is not clear to me how would I achieve the goal even through context drawing.
Any idea would be much appreciated.
Try this
Create a Custom UILabel SubClass and Override the following method
- (void)drawTextInRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetShadow(context, CGSizeMake(0.0, 0.0), 10);
CGContextSetShadowWithColor(context, CGSizeMake(0.0, 0.0), 10, [UIColor blackColor].CGColor);
[super drawTextInRect:rect];
CGContextRestoreGState(context);
}
and this bottomColorLayer to the Label
CALayer *bottomColorLayer = [CALayer layer];
bottomColorLayer.frame = CGRectMake(0, labelRect.size.height/2, labelRect.size.width, labelRect.size.height/2);
bottomColorLayer.backgroundColor = [[UIColor colorWithWhite:0 alpha:.5] CGColor];
[label.layer insertSublayer:bottomColorLayer above:(CALayer *)label.layer];
or If you want Gradient
CAGradientLayer *bottomGradient = [CAGradientLayer layer];
bottomGradient.frame = CGRectMake(0, labelRect.size.height/2, labelRect.size.width, labelRect.size.height/2);
bottomGradient.cornerRadius = 0.0f;
bottomGradient.colors = #[(id)[[UIColor colorWithWhite:1 alpha:.5] CGColor], (id)[[UIColor colorWithWhite:0 alpha:.5] CGColor]];
[label.layer insertSublayer:bottomGradient above:(CALayer *)label.layer];
Use an explicit shadow path that's the shape you want. It sounds like you want a shadow the same shape as your text, but larger, with each shadow-letter centered on its corresponding letter. Once you have that, use the shadow radius to soften the edges of the shadow to whatever degree you want.
The code you have relies on the shadow radius alone to make the shadow larger than the text, which removes your ability to control the softness.
Try with the code below :-
[_testLable setText:#"TION ERRO"];
[_testLable setTextColor:[UIColor whiteColor]];
[_testLable setFont:[UIFont boldSystemFontOfSize:22] ];
_testLable.layer.shadowOffset = CGSizeMake(0, 0);
_testLable.layer.shadowRadius = 10.0;
_testLable.layer.shouldRasterize = YES;
_testLable.layer.shadowOpacity = 1;
_testLable.layer.shadowColor = [UIColor blackColor].CGColor;
_testLable.layer.masksToBounds = NO;
CGPathRef shadowPath = CGPathCreateWithRect(_testLable.bounds, NULL);
_testLable.layer.shadowPath = shadowPath;
CGPathRelease(shadowPath);
Its output is like this:-

Resources