I don't know why this stopped working, but this chunk of code is crashing my device when I try drawing any part of it. I'm new to core graphics so any pointers or suggestions would be a great help. Thanks!
// Style
CGContextRef context = UIGraphicsGetCurrentContext();
// Colors
CGColorRef fillBox = [UIColor colorWithRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:1.0].CGColor;
CGColorRef fillBoxShadow = [UIColor colorWithRed:77.0/255.0 green:77.0/255.0 blue:77.0/255.0 alpha:1.0].CGColor;
CGRect box = CGRectMake(5, 5, self.frame.size.width - 10, self.frame.size.height - 10);
// Shadow
CGContextSetShadowWithColor(context, CGSizeMake(0, 0), 1.0, fillBoxShadow);
CGContextAddRect(context, box);
CGContextFillPath(context);
// Box
CGContextSetFillColorWithColor(context, fillBox);
CGContextAddRect(context, box);
CGContextFillPath(context);
If your project is using ARC, then these two lines might be part of your problem:
CGColorRef fillBox = [UIColor colorWithRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:1.0].CGColor;
CGColorRef fillBoxShadow = [UIColor colorWithRed:77.0/255.0 green:77.0/255.0 blue:77.0/255.0 alpha:1.0].CGColor;
ARC is releasing the UIColor object and thus the CGColorRef. You need to retain the CGColorRef and then release it when you are done with it.
I would write the code something like this:
UIColor *fillBox = [UIColor colorWithRed:250.0/255.0 green:250.0/255.0 blue:250.0/255.0 alpha:1.0];
UIColor *fillBoxShadow = [UIColor colorWithRed:77.0/255.0 green:77.0/255.0 blue:77.0/255.0 alpha:1.0];
and then use fillBox.CGColor and fillBoxShadow.CGColor later on in the method.
Instead of doing
CGContextAddRect(context, box);
CGContextFillPath(context);
Try using CGContextFillRect.
You can't fill a path you haven't added to the context beforehand.
Note: you could do
CGContextAddPath(context, [UIBezierPath pathWithRect:box].CGPath);
CGContextFillPath(context);
but that's a bit overkill compared to just filling a rect.
(Not sure about the pathWithRect: syntax, but it exists.)
Related
I'm running the following code in viewDidLoad, it is applying the glow outside the label not on the text. Please advise.
lbl_score.font = myfont;
lbl_score.alpha = 1.0;
lbl_score.textColor = UIColor.greenColor;
lbl_score.layer.shadowColor = [[UIColor blueColor] CGColor];
lbl_score.layer.shadowOffset = CGSizeMake(0.0, 0.0);
lbl_score.layer.shadowRadius = 30.0f;
lbl_score.layer.shadowOpacity = 0.9;
lbl_score.layer.masksToBounds = NO;
I've imported QuartzCore/QuartzCore.h". I would like to apply the glow only on the label text.
Thanks
To apply a glow to the actual text in a label, you have to override drawTextInRect on the label itself. You're setting a shadow on the label's layer, which is a rectangle.
The override is quite simple. You just adjust the graphics context, call super, then restore the graphics context:
-(void)drawTextInRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeZero, 30.0, [UIColor blueColor].CGColor);
[super drawTextInRect:rect];
CGContextRestoreGState(context);
}
You are putting a shadow on the layer, which is rectangular. UILabel has shadowColor and shadowOffset properties which you should use instead. You can’t set a separate opacity for the shadow this way, but you can bake it into the UIColor that you pass for the shadow color.
lbl_score.font = myfont;
lbl_score.alpha = 1.0;
lbl_score.textColor = UIColor.greenColor;
lbl_score.shadowColor = [[UIColor blueColor] colorWithAlphaComponent:0.9];
lbl_score.shadowOffset = CGSizeMake(0.0, 0.0);
Unfortunately, you can’t set a shadow radius in this way. If you need to change the radius, look at doing your own custom drawing in -drawRect: instead.
I found code similar to jrturton ,but with more customisation.
This is working for me.
DTGlowingLabel.h
#interface DTGlowingLabel : UILabel {
}
#end
DTGlowingLabel.m
#import "DTGlowingLabel.h"
#implementation DTGlowingLabel
- (void) drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
UIColor *insideColor = [UIColor colorWithRed:69.0/255.0 green:254.0/255.0 blue:0 alpha:1];
UIColor *outlineColor = [UIColor colorWithRed:22.0/255.0 green:145.0/255.0 blue:0 alpha:0.8];
UIColor *blurColor = [UIColor colorWithRed:104.0/255.0 green: 248.0/255.0 blue:0 alpha:0.7];
CGContextSetStrokeColorWithColor(ctx, outlineColor.CGColor);
CGContextSetFillColorWithColor(ctx, insideColor.CGColor);
CGContextSetLineWidth(ctx, self.font.pointSize/60.0);
CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), self.font.pointSize / 10.0, blurColor.CGColor);
CGContextSetTextDrawingMode(ctx, kCGTextFillStroke);
[self.text drawInRect:self.bounds withFont:self.font lineBreakMode:self.lineBreakMode alignment:self.textAlignment];
}
#end
Source : http://www.cocoanetics.com/2010/01/uilabels-with-neon-effect/
The code below results in a pure red square:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 5.0f);
CGContextStrokeRect(context, rect);
}
But the code below results in a white square when what I'd expect is a different shade of red. Can anyone tell me why this is?
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor* boxColour = [UIColor colorWithRed:217 green:37 blue:70 alpha:1.0];
CGContextSetStrokeColorWithColor(context, boxColour.CGColor);
CGContextSetLineWidth(context, 5.0f);
CGContextStrokeRect(context, rect);
}
The colorWithRed:green:blue:alpha: method of the UIColor class takes parameters in the range 0.0 to 1.0. You probably just need to divide all the values (except alpha) by 255.0f:
UIColor* boxColour = [UIColor colorWithRed:217/255.0f green:37/255.0f blue:70/255.0f alpha:1.0f];
Apple Documentation
I have a UIColor initiated with [UIColor colorWithRed:Green:Blue:Alpha] and I want to extract its corresponding CGColor to use with CGContextSetFillColorWithColor.
I tried [[UIColor colorWithRed...] CGColor] but for some reason I get no coloring.I
[[UIColor colorWithRed:216 green:156 blue:1 alpha:1] CGColor]
The weird thing is that when I use:
[[UIColor orangeColor] CGColor]
It works just fine.
Any ideas?
Thanks!
EDIT:
The actual code:
CGRect rect = CGRectMake(0.0, 0.0, width, height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:216 green:156 blue:1 alpha:1].CGColor);
CGContextFillRect(context, rect);
self.image = UIGraphicsGetImageFromCurrentImageContext();
I don't think its code-related - again, if I change the UIColor to a constant color it all works.
The purpose of the code is to create an UIImage filled with a specific color.
My goal is
1. add gradient for my view (done)
2. add drop shadow for the bottom edge of my view ( issue at here )
What I am doing is :
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *whiteColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
UIColor *lightGrayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0];
CGRect paperRect = self.bounds;
// Fill with gradient
[self drawLinearGradient:context for:paperRect start:whiteColor.CGColor end:lightGrayColor.CGColor];
CGContextSetStrokeColorWithColor(context, [UIColor lightGrayColor].CGColor);
CGContextSetLineWidth(context, .9);
CGContextStrokeRect(context, paperRect);
// Add shadow
CGContextSetShadowWithColor(context, CGSizeMake(0, self.frame.size.height), 9.0, [UIColor blueColor].CGColor);
}
-(void)drawLinearGradient:(CGContextRef)context for:(CGRect)rect start:(CGColorRef)startColor end:(CGColorRef)endColor {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
However, what I am getting is the picture below without shadow at all
Am I on the right track but missing something in the middle ? Please help if you have any ideas..
You need to set the shadow properties before drawing whatever it is that's supposed to have the shadow. Put your call to CGContextSetShadowWithColor before the call to CGContextStrokeRect.
Also, the offset should probably not be as large as you're making it. The shadow offset controls how much the shadow is offset from the pixels that were drawn with that shadow, so unless you want the shadow to actually start very far away from your rect you probably want an offset of just a pixel or so, like CGSizeMake(0.0, 1.0).
I have a custom UIView which draws a path like so
- (void)drawRect:(CGRect)rect{
[[UIColor blackColor] setStroke];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColor(ctx, CGColorGetComponents(self.color));
CGContextFillPath(ctx);
UIBezierPath *thePath = [UIBezierPath bezierPath];
thePath.lineWidth = _lineWidth;
_center = CGPointMake(rect.size.width, rect.size.height);
[thePath moveToPoint:_center];
[thePath addArcWithCenter:_center radius:rect.size.width startAngle:M_PI endAngle:M_PI+degreesToRadians(_angle)clockwise:YES];
[thePath closePath];
[thePath fill];
}
My custom UIView also has a method to change the filling color
- (void) changeColor:(UIColor *) newColor {
self.color = [newColor CGColor];
[self setNeedsDisplay];
}
If I call the changeColor: method with any of the predefined colors such as
[UIColor redColor]
everything works fine. Instead if i try to give it a custom color such as
UIColor* color = [UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0f];
the color of my custom UIView flicker between white, red and blue randomly.
Any ideas of why is that?
Thank you in advance!
Try:
CGContextSetFillColorWithColor(ctx, self.color.CGColor);
instead of:
CGContextSetFillColor(ctx, CGColorGetComponents(self.color));
When you are using this method call :
[UIColor redColor];
For optimization purposes, UIColor return an object with only 2 components because he don't need the other one. (This is made possible with the mechanism of Class clustering).
That's maybe why your code show some differences between this two colors.