How do I apply an opacity gradient on a UIView? - iphone

I would like my UIView to fade from 100% opacity to 0% opacity. Any thoughts on how I can do this?

Ray Wenderlich has a great tutorial on setting gradients for objects. My suggestion is to modify the following code to suit your needs.
//Ray's code:
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor,
CGColorRef endColor) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = [NSArray arrayWithObjects:(id)startColor, (id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
(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);
}

If the view, together with its labels, is sitting on some static background image or color, a quick and dirty trick is to create gradient PNGs of that image or color and place them over the view.
Otherwise, see if you can adapt this CALayer gradient mask solution for your view.

Related

Image sharpness goes away with drawing gradient effect on it

I have an image (with X & 2X variants) which look sharp and clean on the retina device. But I wanted a gradient effect on it. Once I draw the gradients on it, image looses the sharpness, I guess because of gradients are not put on exact image boundaries. Any suggestion how to fix this. I am attaching the images (With and without gradient effect) as well as my gradient code:
- (UIImage *)tintedWithLinearGradientColors:(NSArray *)colorsArray forImageNamed:(NSString *)iImageName {
// Load image
UIImage *myIconImage = [UIImage imageNamed:iImageName];
// Create gradient
UIColor *colorOne = [colorsArray objectAtIndex:1]; // top color
UIColor *colorTwo = [colorsArray objectAtIndex:0]; // bottom color
NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, (id)colorTwo.CGColor, nil];
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL);
UIGraphicsBeginImageContext(myIconImage.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, myIconImage.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGRect rect = CGRectMake(0, 0, myIconImage.size.width, myIconImage.size.height);
// image drawing code
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextDrawImage(context, rect, myIconImage.CGImage);
// draw tint color, preserving alpha values of original image
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextClipToMask(context, rect, myIconImage.CGImage);
CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0, myIconImage.size.height), 0);
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return coloredImage;
}
You need to add this gradient by code? If don't, add the gradient on photoshop or other software and then add the image to your project already with the gradient.
Replacing the line
UIGraphicsBeginImageContext(myIconImage.size);
with
UIGraphicsBeginImageContextWithOptions(myIconImage.size, NO, myIconImage.scale);
worked for me.

How to make a fading effect with Core Graphics?

I want to make an effect like what you see on the right side of the first cell here:
I'm guessing it's some sort of overlay view with a gradient, but I just can't figure out how it's configured with transparency. I tried making my own overlay view with a gradient and set the alpha of the colors down, but it just shows up as a gray - white gradient.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *gradBegin = [UIColor colorWithWhite:1.0 alpha:0.8];
UIColor *gradEnd = [UIColor colorWithWhite:1.0 alpha:0.6];
NSArray* gradientColors = [NSArray arrayWithObjects:
(id)gradBegin.CGColor,
(id)gradEnd.CGColor, nil];
CGFloat gradientLocations[] = {0, 1};
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradientColors, gradientLocations);
CGContextDrawLinearGradient(context, gradient, CGPointMake(rect.origin.x, rect.origin.y + rect.size.height/2.0),
CGPointMake(rect.origin.x + rect.size.width, rect.origin.y + rect.size.height/2.0), 0);
What exactly is going on in this screenshot, and how can I replicate it?
I wrote a simple UIView class that will draw itself faded. It is a basic UIView with the drawRect overrided:
- (void)drawRect:(CGRect)rect
{
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor* gradBegin = [UIColor colorWithWhite:1 alpha:0];
UIColor* gradEnd = [UIColor colorWithWhite:1 alpha:1];
NSArray* gradColours = [NSArray arrayWithObjects:
(id)gradBegin.CGColor,
(id)gradBegin.CGColor,
(id)gradEnd.CGColor,
(id)gradEnd.CGColor, nil];
CGFloat gradLocs[] = { 0, 0.5, 0.9, 1 };
CGGradientRef gradient = CGGradientCreateWithColors(colourSpace, (__bridge CFArrayRef)gradColours, gradLocs);
CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(self.frame.size.width, 0), 0);
CGGradientRelease(gradient);
CGColorSpaceRelease(colourSpace);
}
This works if overlayed over your view and the view's background is white.
While this certainly can be done with Core Graphics, it's infinitely easier to add a transparent PNG to your project with the appropriate width and 1 pixel height and then position a UIImageView in your table cell over the content to create this effect.
The gradient drawing code in your question looks ok, although I haven't tested it. I suggest setting gradBegin.alpha = 0 and gradEnd.alpha = 1. Also, the last line could be simplified:
CGContextDrawLinearGradient(context, gradient, rect.origin,
CGPointMake(CGRectGetMaxX(rect), rect.origin.y, 0);
And don't forget to CGGradientRelease(gradient).
Anyway, other than that, you need to set overlayView.opaque = NO.

Drawing linear gradient in a rect works on iOS 5.x but not 4.x

I have some code that I use to fill a view with a linear gradient, I've refactored this into a helper method. This draws fine on iOS 5.x but when I tried running on 4.3.5 I don't get anything. I've checked all the CG calls and they all are supported on 4.0 or older, it look so simplistic I can't see why it doesn't work on 4.x.
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef startColor = [UIColor lightGrayColor].CGColor;
CGColorRef endColor = [UIColor blackColor].CGColor;
CGRect paperRect = self.frame;
[GraphicsHelpers drawLinearGradientWithContext:context
inRect:paperRect
startColor:startColor
endColor:endColor];
}
Here is that method
+ (void)drawLinearGradientWithContext:(CGContextRef)context inRect:(CGRect)rect startColor:(CGColorRef)startColor endColor:(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);
}
I found most of this code here and was working great until I started testing on older OS versions as I'm close to release.
I had the same problem, solved worked around it by creating the gradient using
CGGradientCreateWithColorComponents
.. instead of CGGradientCreateWithColors.
So, for a gradient from light gray to black you need to do the following:
CGFloat colors[8] = {
0.9f, 0.9f, 0.9f, 1.0f, // light gray
0.0f, 0.0f, 0.0f, 1.0f // black
};
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 2);
This works in both iOS 4 and 5.
I had to face the same problem as a tried to fill a view with a gradient. Finally I found out that the specific UIColor( redColor, whiteColor, etc) is incompatible with CGColors.
Using ([UIColor whiteColor].CGColor) serves a CGColor which is not imcompatible or not supported in ios 4.3. For that reason I tried out to use [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0].CGColor. This could be converted into CGColor space and finally I had a gradient in my view also with ios 4.3 and ios 5.x
If you're using supported API and you're getting different results from one version of the OS to another, file a bug report.

iPhone : can't control the width of drawing gradients?

I need to draw a box filled with a gradient. I'm using a UIView and overwriting the -drawRect method.
Here is my code (simplified):
CGContextRef c = UIGraphicsGetCurrentContext();
CGFloat components[8] = {158.0/255.0,36.0/255.0,134.0/255.0,1.0,115.0/255.0,26.0/255.0,93.0/255.0,1.0};
CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[2] = {0.0,1.0};
CGGradientRef glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, 2);
CGPoint topCenter = CGPointMake(10, 0);
CGPoint bottomCenter = CGPointMake(10, 10);
CGContextDrawLinearGradient(c, glossGradient, topCenter, bottomCenter, 0);
The gradient fill at present fills the entire width of the view! What can I do to control the width of the gradient-filled box I'm drawing?
Nevermind.. Found the answer. I need to clip my CGContextRef to match the CGRect I wanted:
CGContextClipToRect(c, currentBounds);

How to do a radar animation in the iPhone SDK?

Does anyone know how to animate a radar animation like the image below?
alt text http://img197.imageshack.us/img197/7124/circle0.png
With it growing outwards? I have to draw the circle using Quartz or some other way?
To draw a static circle in a UIView subclass:
- (void)drawRect:(CGRect)rect
{
CGRect rect = { 0.0f, 0.0f, 100.0f, 100.0f };
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextSetLineWidth(context, 2.0f);
CGContextAddEllipseInRect(context, rect);
CGContextStrokePath(context);
}
From there you just need to animate it with a timer, vary the size of the rect, and add more circles.