This seems simple enough - perhaps you can help me find the solution?
I wrote a custom drop shadow for a UIButton. I'm attempting to place it at the lowest index of the UIButton's layer stack. Unfortunately, it isn't being placed beneath the rest of the UIButton.
The Code:
//UIButton type custom
alarmSetterButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *img = [UIImage imageNamed:#"rootSchedulerButton"];
//Scaling
float delta = 2.4f;
if (IS_IPHONE_5) delta = 2.0f;
[alarmSetterButton setFrame:CGRectMake(0.0f, 0.0f, (img.size.width/delta), (img.size.height/delta))];
[alarmSetterButton setBackgroundImage:img forState:UIControlStateNormal];
[alarmSetterButton setTitle:#"" forState:UIControlStateNormal];
[alarmSetterButton addTarget:self action:#selector(setSecondaryView:) forControlEvents:UIControlEventTouchUpInside];
//the colors for the gradient
UIColor *high = [UIColor colorWithWhite:0.0f alpha:1.0f];
UIColor *low = [UIColor colorWithWhite:0.0f alpha:0.0f];
//The gradient, simply enough. It is a rectangle
CAGradientLayer * gradient = [CAGradientLayer layer];
[gradient setFrame:[b bounds]];
[gradient setColors:[NSArray arrayWithObjects:(id)[high CGColor], (id)[low CGColor], nil]];
[gradient setAnchorPoint:CGPointMake(0.5f, 0.0f)];
[gradient setTransform:CATransform3DMakeRotation(315.0 / 180.0 * M_PI, 0.0, 0.0, 1.0)];
// What needs altered
[alarmSetterButton.layer insertSublayer:gradient below:alarmSetterButton.layer];
I found the solution. Instead of using UIButton's setBackroundImage:forState: method I wrote a new CALayer to contain the contents of the image.
Thanks for the help.
:)
Try this, it places the layer at position zero in the stack, i.e. the bottom.
[alarmSetterButton.layer insertSublayer:gradient atIndex:0];
Related
I am using below code to add text and border to selected image from cameraroll.
-(UIImage*)image:(UIImage*)image withText:(NSString*)text atPoint:(CGPoint)point{
if (text) {
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
[image drawInRect:rect];
NSDictionary *attributes = #{NSFontAttributeName : [UIFont boldSystemFontOfSize:80],
//NSStrokeWidthAttributeName : #(4),
NSStrokeColorAttributeName : [UIColor whiteColor]};
[text drawAtPoint:point withAttributes:attributes];
CALayer *l = [self.imageView layer];
[l setBorderWidth:10.0];
[l setBorderColor:[[UIColor blueColor] CGColor]];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
return newImage;
}
When i click on save button in my app, i am saving edited image to cameraroll.But edited image inside cameraroll only has text without any added border. Whether i am missing anything in above code to add and save border around image? Is there any other way to add border other than CALayer?
Replace this:
CALayer *l = [self.imageView layer];
[l setBorderWidth:10.0];
[l setBorderColor:[[UIColor blueColor] CGColor]];
With this:
UIBezierPath *rectangleBezier = [UIBezierPath bezierPathWithRect:rect];
rectangleBezier.lineWidth = 20.0f; // 10 * 2 because line drawn from the center of edge
[[UIColor blueColor] setStroke];
[rectangleBezier stroke];
Remarks:
CALayer *l = [self.imageView layer]; has nothing to do with UIImage data. imageView's layer change imageView presentation. Not the content of UIImage.
I will respond to "Adding a border around an UIImage in a UIView"
From far, the easiest method is to insert another view in the view hierarchy.
[self.view insertSubview:({
UIView * border = [[UIView alloc]
initWithFrame:CGRectInset(self.imageView.frame, -1, -1)];
border.backgroundColor = [UIColor blueColor];
border;
})
belowSubview:self.imageView];
I have a background on the homescreen of my app which want to expand to fill the screen when it is rotated though I have tried to give it autoresizingmasks though it won't let as it is a CALayer. At the moment when you resize the screen there is a big white space on the right left by where the gradient was
Here is the code I am using to initialize the gradient:
UIColor *highColor = [UIColor colorWithRed:0.0f/255.0f green:128.0f/255.0f blue:214.0f/255.0f alpha:1.000];
UIColor *lowColor = [UIColor colorWithRed:5.0f/255.0f green:69.0f/255.0f blue:150.0f/255.0f alpha:1.000];
gradientBackground = [CAGradientLayer layer];
[gradientBackground setFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
[gradientBackground setColors:[NSArray arrayWithObjects:(id)[highColor CGColor], (id)[lowColor CGColor], nil]];
backgroundLayer = [CALayer layer];
[backgroundLayer setFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
[backgroundLayer setMasksToBounds:YES];
[backgroundLayer addSublayer:gradientBackground];
backgroundObject = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
[self.view addSubview:backgroundObject];
[[backgroundObject layer] insertSublayer:backgroundLayer atIndex:0];
[backgroundObject setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
Any advice as to how to fix this issue will be muchly appreciated
I managed to work out a way around using a CALayer and just set the background of the view to an image of a gradient like this:
UIGraphicsBeginImageContext(self.view.frame.size);
[[UIImage imageNamed:#"home-gradient.png"] drawInRect:self.view.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:image];
Can you embed the layer in a view, then set the resizing mask on the view? You could subclass both UIView and CALayer, then implement the view's +layerClass method to return your layer subclass and use the layer subclass to draw the gradient.
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:-
I made button whit little arrow on the bottom like on the image.
But I to add rounded corner. Here is my problem. If I add rounded corner then my button are mask to bounds and arrow is mask out. If I set setMasksToBounds:NO then button is not cornered.
+ (UIButton*)MCustomButtonSelected:(UIButton*)button andColor:(UIColor*)color shadowColor:(UIColor *)shadowColor andFontSize:(int)fontSize numberOfLines:(int)lines{
button.titleLabel.numberOfLines = lines;
UIImage * radialGradient = [Color getRadialGradientImage:button.frame.size centre:CGPointMake(0.5, 0.6) radius:1.4 startColor:color endColor:shadowColor];
[button setBackgroundColor:[UIColor colorWithPatternImage:radialGradient]];
[button.layer setBorderColor:[[UIColor clearColor] CGColor]];
button.layer.cornerRadius = 5;
[button.layer setMasksToBounds:NO]; // here is the problem
[button.layer setOpaque:NO];
[button.titleLabel setTextAlignment:NSTextAlignmentCenter];
[button.titleLabel setFont:[UIFont fontWithName:[Fonts mainFontName] size:fontSize]];
button.titleLabel.adjustsFontSizeToFitWidth = YES;
[button.titleLabel setShadowOffset:CGSizeMake(0.5, 0.5)];
[button setTitleShadowColor:[Color buttonNormalTextShadowColor] forState:UIControlStateNormal];
[button setTitleColor:[Color buttonNormalTextColor] forState:UIControlStateNormal];
[button setTitleShadowColor:[Color buttonPressTextShadowColor] forState:UIControlStateHighlighted];
[button setTitleColor:[Color buttonPressTextColor] forState:UIControlStateHighlighted];
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4);
UIView * pointer = [[UIView alloc]initWithFrame:CGRectMake(button.frame.size.width/2-5, button.frame.size.height-5, 10, 10)];
pointer.backgroundColor = color;
pointer.transform = transform;
pointer.tag = 10;
pointer.clipsToBounds = NO;
[button addSubview:pointer];
[button sendSubviewToBack:pointer];
return button;
}
Can anyone help me out.
Do this:
UIBezierPath *path = "create a path representing ur desired shape, along with the arrow"
CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = path.CGPath;
button.layer.mask = shape;
Take a look at the following image:
As you can see the edges are sharp rectangle and they are coming out of the rounded corner button. How can I not show the edges and only show the round button?
UPDATE (Solution):
I used the following code to achieve the round corners:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.stopButton.bounds
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(12.0, 12.0)];
// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.stopButton.bounds;
maskLayer.path = maskPath.CGPath;
// Set the newly created shape layer as the mask for the image view's layer
self.stopButton.layer.mask = maskLayer;
NEW PROBLEM:
This code gives me the error on the startButtonRound.layer.cornerRadius line.
UIButton *roundStartButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
roundStartButton.frame = CGRectMake(10, 10, 100, 20);
[roundStartButton setBackgroundImage:[UIImage imageNamed:#"green_gradient.jpg"] forState:UIControlStateNormal];
roundStartButton.layer.cornerRadius = 12.0;
UIBarButtonItem *startButton = [[UIBarButtonItem alloc] initWithCustomView:roundStartButton];
You could do this with CALayer alone:
CALayer *myLayer = [CALayer layer];
[myLayer setMasksToBounds:YES];
[myLayer setCornerRadius:5.0f];
[myLayer setBorderWidth:1.0f];
[myLayer setBorderColor: [[UIColor blackColor] CGColor]];
[myLayer setBackgroundColor: [[UIColor whiteColor] CGColor]];
You'll also want to include the QuartzCore framework and include the frameworks header in your own.
#include <QuartzCore/QuartzCore.h>
Hope this helps
Tim
I think all that can be accomplished with:
self.stopButton.layer.cornerRadius = 12.0;
But did you try
self.stopButton.opaque = NO;
self.stopButton.backgroundColor = [UIColor clearColor];
?
form the look of the image you have set your UIButton bckground color to 'White'. Make it 'Clear Color'.