Adding shade to label - iphone

I need the label as
I created one label subclass.Where I write the code as,
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
UIColor * textColor = [UIColor colorWithRed:57.0/255.0 green:100.0/255.0 blue:154.0/255.0 alpha:1.0];
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, 3.5);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetTextDrawingMode(c, kCGTextFillStroke);;
self.textColor = [UIColor whiteColor];
[super drawTextInRect:rect];
CGContextSetTextDrawingMode(c, kCGTextFill);
self.textColor = textColor;
// self.shadowColor = [UIColor colorWithRed:11.0/255.0 green:63.0/255.0 blue:126.0/255.0 alpha:1.0];
//self.shadowOffset = CGSizeMake(0.5, -0.5);
[super drawTextInRect:rect];
}
By this I am getting the blue color text and white outline to that text.But I need to get the dark blue color shade. How can I do this?
Please help me.

You should probably have a look at the CGContextSetShadowWithColor method.
CGContextSetShadowWithColor (
context,
shadowSize,
shadowBlur,
color
);
I found an article that could help you on this website : http://majicjungle.com/blog/191/
EDIT
The following code works:
- (void)drawRect:(CGRect)rect
{
UIColor * textColor = [UIColor colorWithRed:57.0/255.0 green:100.0/255.0 blue:154.0/255.0 alpha:1.0];
CGContextRef c = UIGraphicsGetCurrentContext();
//save the context before add shadow otherwise the shadow will appear for both stroke and fill
CGContextSaveGState(c);
//this is where I add the shadow, and it works
CGContextSetShadowWithColor(c, CGSizeMake(2, 2), 3, [[UIColor grayColor] CGColor]);
CGContextSetLineWidth(c, 3.5);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetTextDrawingMode(c, kCGTextStroke);;
self.textColor = [UIColor whiteColor];
[super drawTextInRect:rect];
//restore the context to clear the shadow
CGContextRestoreGState(c);
CGContextSetTextDrawingMode(c, kCGTextFill);
self.textColor = textColor;
[super drawTextInRect:rect];
}

Have you tried using the standard quartz properties like:
label.layer.shadowColor
label.layer.shadowOffset
(you need the QuartzCore framework in your project and to import the header).

Related

Color Overlay UIButton Image

I'm having this issue when trying to overlay a UIButton's Image with a color.
The overlay color is appearing underneath the Image.
Here is the code that I have in my drawRect method (I have subclassed UIButton):
(void)drawRect:(CGRect)rect
{
CGRect bounds = self.imageView.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextTranslateCTM(context, 0.0, self.imageView.image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextClipToMask(context, bounds, [self.imageView.image CGImage]);
CGContextFillRect(context, bounds);
}
Any ideas on how to get the red color on top of the Image?
Succeeded with this hacky code:
- (void)drawRect:(CGRect)rect
{
UIImage* img = [self imageForState:UIControlStateNormal];
[self setImage:nil forState:UIControlStateNormal];
CGRect bounds = self.imageView.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2].CGColor);
CGContextDrawImage(context, bounds, img.CGImage);
CGContextFillRect(context, bounds);
}
It seems the image is drawn after drawRect so unless you make it nil, it goes on top of whatever you draw there.
This is solution is not final. I'll edit it with what I get to next.
EDIT: The right solution is to add a semi-transparent UIView on top of the image like this:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIView* tintView = [[UIView alloc] initWithFrame:self.bounds];
tintView.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2];
tintView.userInteractionEnabled = NO;
[self addSubview:tintView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
UIView* tintView = [[UIView alloc] initWithFrame:self.bounds];
tintView.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2];
tintView.userInteractionEnabled = NO;
[self addSubview:tintView];
}
return self;
}
Note: you should do this in your UIButton subclass.

Drawing Shadowed Rectangle at iOS

I am trying to draw an image like below with libraries in iOS; but i couldn't.
I think it is very easy to draw but i couldn't achieve.
After i accomplish to draw i will place a label over it.
Use this as your drawRect method:
- (void)drawRect:(CGRect)rect
//// General Declarations
CGContextRef context = UIGraphicsGetCurrentContext();
//// Shadow Declarations
UIColor* shadow = [UIColor blackColor];
CGSize shadowOffset = CGSizeMake(1, 1);
CGFloat shadowBlurRadius = 2;
//// Frames
CGRect frame = rect;
//// Abstracted Graphic Attributes
CGRect shadowBoxRect = CGRectMake(CGRectGetMinX(frame) + 0, CGRectGetMinY(frame) + 0, 40, 40);
CGFloat shadowBoxCornerRadius = 4;
//// ShadowBox Drawing
UIBezierPath* shadowBoxPath = [UIBezierPath bezierPathWithRoundedRect: shadowBoxRect cornerRadius: shadowBoxCornerRadius];
[[UIColor lightGrayColor] setFill];
[shadowBoxPath fill];
////// ShadowBox Inner Shadow
CGRect shadowBoxBorderRect = CGRectInset([shadowBoxPath bounds], -shadowBlurRadius, -shadowBlurRadius);
shadowBoxBorderRect = CGRectOffset(shadowBoxBorderRect, -shadowOffset.width, -shadowOffset.height);
shadowBoxBorderRect = CGRectInset(CGRectUnion(shadowBoxBorderRect, [shadowBoxPath bounds]), -1, -1);
UIBezierPath* shadowBoxNegativePath = [UIBezierPath bezierPathWithRect: shadowBoxBorderRect];
[shadowBoxNegativePath appendPath: shadowBoxPath];
shadowBoxNegativePath.usesEvenOddFillRule = YES;
CGContextSaveGState(context);
{
CGFloat xOffset = shadowOffset.width + round(shadowBoxBorderRect.size.width);
CGFloat yOffset = shadowOffset.height;
CGContextSetShadowWithColor(context,
CGSizeMake(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)),
shadowBlurRadius,
shadow.CGColor);
[shadowBoxPath addClip];
CGAffineTransform transform = CGAffineTransformMakeTranslation(-round(shadowBoxBorderRect.size.width), 0);
[shadowBoxNegativePath applyTransform: transform];
[[UIColor grayColor] setFill];
[shadowBoxNegativePath fill];
}
CGContextRestoreGState(context);
}
Inner shadows are hard to do with CoreGraphics -- basically, you need to negate your path and draw a drop shadow below it, clipped to your original path.
You can take a look at PaintCode and it will show you the code. It has a 15-min demo mode if you don't want to purchase it, that should be enough for your needs.
You could try this:
#import <QuartzCore/QuartzCore.h>
and in your code , after making the your view set these:
self.layer.cornerRadius = x;
self.layer.masksToBounds = TRUE;
This allows you to have rounded corners on your view. And if you calculate the radius to match your view , you should get the desired look.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor grayColor];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context =UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
// And draw with a blue fill color
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
// Draw them with a 2.0 stroke width so they are a bit more visible.
CGContextSetLineWidth(context, 2.0);
CGContextAddRect(context, self.bounds);
CGContextStrokePath(context);
// Close the path
CGContextClosePath(context);
// Fill & stroke the path
CGContextDrawPath(context, kCGPathFillStroke);
self.layer.cornerRadius = self.bounds.size.width/12;
self.layer.masksToBounds = TRUE;
}
I think it will be helpful to you.
Try the below code where myView is the UIView to which you want to set the shadow.
myView.layer.cornerRadius = 5.0f;
myView.layer.masksToBounds = YES;
[myView.layer setShadowColor:[[UIColor blackColor] colorWithAlphaComponent: 0.5]];
[myView.layer setShadowOffset:CGSizeMake(0, -1)];
Hope this helps.-

CGContextFillRect not drawing a rectangle?

I have this code:
CGColorRef darkColor = [[UIColor colorWithRed:21.0/255.0 green:92.0/255.0 blue:136.0/255.0 alpha:1.0] CGColor];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, darkColor);
CGContextFillRect(context, CGRectMake(18, 62, 66, 66));
And I just put it in the viewdidload method of my view, but my view doesn't look any different than before. I've tried making it really big and bright red, but it's just not drawing. Is there some other initialization code that I need?
EDIT: After working with the answers given to me, I have this now in my veiwdidload:
[self.view addSubview:[[[imageBackground alloc] init] autorelease]];
and in imageBackground.m:
#implementation imageBackground
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.opaque = YES;
self.backgroundColor = [UIColor clearColor];
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
CGColorRef darkColor = [[UIColor colorWithRed:21.0/255.0 green:92.0/255.0 blue:136.0/255.0 alpha:1.0] CGColor];
darkColor = [[UIColor colorWithRed:255.0 green:0.0 blue:0.0 alpha:1.0] CGColor];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, darkColor);
CGContextFillRect(context, CGRectMake(18, 62, 66, 66));
}
#end
Imagebackground.h subclasses UIView:
#import <UIKit/UIKit.h>
#interface imageBackground : UIView
#end
I still get no results out of it though.
EDIT2: Well, I solved it myself, but then realized progrmr had already told me how to solve it. I had to use [self.view addSubview:[[[imageBackground alloc] initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease]]; instead of just plain alloc init.
Thanks glorifiedhacker for lots of help as well!
You need to subclass UIView (or one of its subclasses) and override the drawRect method:
- (void)drawRect:(CGRect)rect {
CGColorRef darkColor = [[UIColor colorWithRed:21.0/255.0 green:92.0/255.0 blue:136.0/255.0 alpha:1.0] CGColor];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, darkColor);
CGContextFillRect(context, CGRectMake(18, 62, 66, 66));
}
in order to get a valid graphics context into which you can draw. From Apple's documentation on UIView:
View drawing occurs on an as-needed basis. When a view is first shown,
or when all or part of it becomes visible due to layout changes, the
system asks the view to draw its contents. For views that contain
custom content using UIKit or Core Graphics, the system calls the
view’s drawRect: method. Your implementation of this method is
responsible for drawing the view’s content into the current graphics
context, which is set up by the system automatically prior to calling
this method. This creates a static visual representation of your
view’s content that can then be displayed on the screen.
The most simply way, without subclassing, is a procedure for whole code.
void DrawRectFrame(CGContext c, CGRect rc)
{
CGContextMoveToPoint(c, rc.origin.x, rc.origin.y);
CGContextAddLineToPoint(c, rc.origin.x+rc.size.width, rc.origin.y);
CGContextMoveToPoint(c, rc.origin.x+rc.size.width, rc.origin.y);
CGContextAddLineToPoint(c, rc.origin.x+rc.size.width, rc.origin.y+rc.size.height);
CGContextMoveToPoint(c, rc.origin.x+rc.size.width, rc.origin.y+rc.size.height);
CGContextAddLineToPoint(c, rc.origin.x, rc.origin.y+rc.size.height);
CGContextMoveToPoint(c, rc.origin.x, rc.origin.y+rc.size.height);
CGContextAddLineToPoint(c, rc.origin.x, rc.origin.y);
}

How to draw only the outline of a text, but not the fill itself?

I'm drawing text in -drawRect with this method:
[someText drawInRect:rect withFont:font lineBreakMode:someLineBreakMode alignment:someAlignment];
I just want to draw the outline but not the fill!
I've found that I can set CGContextSetFillColorWithColor and just provide an fully transparent color. But I fear this has bad performance impact because probably it does all the heavy drawing work behind the scenes with a transparent color.
Is there a way to just disable the fill-drawing if only outline-drawing is wanted?
Have you tried using kCGTextFillStroke? This might work easily. To use it, just override drawTextInRect
- (void)drawTextInRect:(CGRect)rect {
CGSize shadowOffset = self.shadowOffset;
UIColor *textColor = self.textColor;
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, 1);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetTextDrawingMode(c, kCGTextStroke);
self.textColor = [UIColor whiteColor];
[super drawTextInRect:rect];
CGContextSetTextDrawingMode(c, kCGTextFill);
self.textColor = textColor;
self.shadowOffset = CGSizeMake(0, 0);
[super drawTextInRect:rect];
self.shadowOffset = shadowOffset;
}
EDIT: This answer also appears in a previous incarnation of this question: How do I make UILabel display outlined text?

Large UIImage drawinrect extremely slow on selection

I have a custom UITableView cell that sports an Image, and a headline. I used the fast scrolling example of ABTableViewCell from atebits.
It seems when I select the first row (which is my row with the largest image) it takes a considerable amoun of time to highlight the row, and then push the new view controller.
However when I select any of the other rows, with much smaller images, its almost instant.
Ive attempted to draw the picture using CGContextDrawImage and drawInRect but both yield the same results.
- (void)drawContentView:(CGRect)r highlighted:(BOOL)highlighted {
if ([type isEqualToString:#"first"]) {
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *backgroundColor = [UIColor blackColor];
UIColor *textColor = [UIColor whiteColor];
UIColor *textBackgroundColor = [[UIColor alloc] initWithWhite:0 alpha:.5];
UIColor *highlightColor;
if (highlighted) {
backgroundColor = [UIColor clearColor];
textColor = [UIColor blueColor];
highlightColor = [[UIColor alloc] initWithWhite:0 alpha:.3];
} else {
highlightColor = [UIColor clearColor];
}
[backgroundColor set];
CGContextFillRect(context, r);
[self.picture drawInRect:CGRectMake(0.0, 0.0, 320, 225)];
[textBackgroundColor set];
CGContextFillRect(context, CGRectMake(0, 170, 320, 55));
[textColor set];
[self.title drawInRect:CGRectMake(5, 170, 320, 55) withFont:firstHeadlineFont lineBreakMode:UILineBreakModeWordWrap];
[highlightColor set];
CGContextFillRect(context, r);
} else {
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *backgroundColor = [UIColor blackColor];
UIColor *textColor = [UIColor blueColor];
if (highlighted) {
backgroundColor = [UIColor clearColor];
textColor = [UIColor whiteColor];
}
[backgroundColor set];
CGContextFillRect(context, r);
CGPoint p;
p.x = 0;
p.y = 0;
[self.picture drawInRect:CGRectMake(0.0, 0.0, 44, 44)];
[textColor set];
p.x += 44 + 6; // space between words
[self.title drawAtPoint:p withFont:[UIFont systemFontOfSize:20]];
}
}
EDIT:
IS there anything I can do to speed this up? I am caching the image and reading it as well.
I realized I was using a very very large version of the image for my first row, I was able to scale it down before I pulled it from the webserver and this vastly improved performance. NOTE: double check your dimensions are not huge. IE: 2184x1456 hahah