I know that it is possible to add a transparent/translucent overlay view on a UIImagePickerController by using the drawrect method and by adjusting the alpha value of a CGRect UIColor for example. But is it possible to get a blurry effect instead of the translucent one ? I hope I am clear enough...
Thanks !
EDIT (add code)
- (void)drawRect:(CGRect)rect{
CGFloat toolbarSize = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? 0 : 80;
CGFloat width = CGRectGetWidth(self.frame);
CGFloat height = CGRectGetHeight(self.frame) - toolbarSize;
CGFloat heightSpan = floor(height / 2 - self.cropSize.height / 2);
CGFloat widthSpan = floor(width / 2 - self.cropSize.width / 2);
//fill outer rect
[[UIColor colorWithRed:0. green:0. blue:0. alpha:0.5] set];
UIRectFill(self.bounds);
//fill inner border
[[UIColor colorWithRed:1. green:1. blue:1. alpha:0.5] set];
UIRectFrame(CGRectMake(widthSpan - 1, heightSpan - 1, self.cropSize.width + 2, self.cropSize.height + 2));
//fill inner rect
[[UIColor clearColor] set];
UIRectFill(CGRectMake(widthSpan, heightSpan, self.cropSize.width, self.cropSize.height));
}
}
I used this framework to achieve a blurry view, worked really well for me
FXBlurView
Related
I wanted to draw a vertical single bar graph. I was trying to do it using DrawRect, but could not able to do so. Can nay one hlep me to knwo if this can be done easily by providing start and end point in view to change the color.
thanks
If you have a custom view, it's just a matter of drawing the lines and rectangles that you want. For example:
- (void)drawRect:(CGRect)rect
{
CGAffineTransform t = CGAffineTransformMakeScale(1, -1);
self.transform = t;
CGFloat baseline = 50;
CGFloat inset = 40;
CGFloat barWidth = 20;
CGFloat barHeight = 80;
CGRect r = CGRectMake(inset + barWidth, baseline, barWidth, barHeight);
UIBezierPath *p = [UIBezierPath bezierPathWithRect:r];
[[UIColor redColor] set];
[p fill];
p = [UIBezierPath bezierPath];
[p moveToPoint:CGPointMake(inset, baseline)];
[p addLineToPoint:CGPointMake(inset + 3 * barWidth, baseline)];
[[UIColor blackColor] set];
[p stroke];
}
produces this:
I've created a UIView subclass with the -drawRect: method above and created an instance of that view that's the size of the window. Note that I flipped the coordinate system using a transform -- you don't have to do that, but drawing with the origin at the lower left corner can be easier.
try this one
1. http://www.raywenderlich.com/13271/how-to-draw-graphs-with-core-plot-part-2
2 OVGraph.- a library for the graphs
I've been trying to replicate the gradient from UINavigationBar to use as a gradient on custom UIButton subclass objects on the same view.
However, I can't figure out how the colors are derived? That is, you only specify one color to set a UINavigationBar's background color- tintColor - but it creates a nice gradient with it seems at least 4 colors?
I'm really just interested in the "inner" top and bottom colors though - just inside the 1px border around the bar... the outer "border" colors do indeed appear different though.
EDIT - 1
Upon further research, it appears the HSB (instead of the RBG as first thought) values are being manipulated to get these different colors.
There is also a convenience method on UIColor to get the HSB values, which should be helpful:
getHue:saturation:brightness:alpha:
Helpful References Found So Far
HSL and HSV Wiki
UIColor Class Reference
Programmatically Lighten a Color
From the book Fundamentals of Interactive Computer Graphics
EDIT - 2
In case you were unaware that you could set a gradient for a background on a UIButton programmatically, here's some references for how to do such:
FUN WITH UIBUTTONS AND CORE ANIMATION LAYERS
Five Tips for Creating Stylish UIButtons (kudos to #cdo for providing this link)
EDIT - 3
I've put together a spreadsheet showing the original and the "inner" gradient colors (disregarding the outer most colors) in HSB values on UINavigationBar and its corresponding "back" button (titles are irrelevant and always displayed white).
Here's a link to the Google doc with the information that I've collected for a few sample colors:
https://docs.google.com/spreadsheet/ccc?key=0AnKVtzkNS9scdGVRN01pa1NQcC1hdThNbEVzQU8wRlE&usp=sharing
Note: these values were found by saving a screenshot using the retina, 3.5" iPhone Simulator (Xcode version 4.6) for iOS 6.1 and eye-dropping the HSB values using PhotoShop.
BOUNTY AWARD CRITERIA
I've opened a bounty on this question to bring more exposure to it and hopefully get a good answer. The answer that I'm looking for:
Provide a method of calculating/closely approximating (in most cases) the RGB or HSB values of the "inner top" and "inner bottom" gradient colors (see spreadsheet) created after setting a tintColor on UINavigationBar.
Bonus points awarded (above initial bounty offering) if you also provide a method for calculating the "inner top" and "inner bottom" gradient colors on the "back" button (which is similar to the navigation bar, but I've found these colors appear to be slightly "darker" usually)?
Short Answer: it is not gradient
Long Answer: After tint color applied, there is a transparent overlay image rendered on top of it.
It is called: UITintedTopBarHighlight#2x.png an it is in UIKit artwork. (uploaded here: http://cl.ly/image/2c2V3t1D1T3L)
It is 2x88 pixel image, and must be repeated horizontally over tinted background.
For back button, it is very similar, but there is also a mask to give it it's shape. UItintedBackButtonHighlight and UITintedBackButtonMask.
It's hard to copy the exact behavior because it seems that Apple is calculating different for different color groups. eg. a light color is slightly darkened while a dark color is lit up.
Same for the bar button item. For some colors the difference for normal "bordered" button and "done"-style button is completely different. Sometimes not noticeable like for turquoise but definitely seeable for orange.
For creating this sample code I used PaintCode a nice tool for prototyping btw..
Copy this code in a UIView subclass or something. Or just grab the pieces code you need.
- (void)drawRect:(CGRect)rect
{
//// General Declarations
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
//// Color Declarations
UIColor* tint = [UIColor colorWithRed: 1 green: 0.66 blue: 0.329 alpha: 1];
CGFloat tintRGBA[4];
[tint getRed: &tintRGBA[0] green: &tintRGBA[1] blue: &tintRGBA[2] alpha: &tintRGBA[3]];
UIColor* lighter = [UIColor colorWithRed: (tintRGBA[0] * 0.58 + 0.42) green: (tintRGBA[1] * 0.58 + 0.42) blue: (tintRGBA[2] * 0.58 + 0.42) alpha: (tintRGBA[3] * 0.58 + 0.42)];
CGFloat lighterRGBA[4];
[lighter getRed: &lighterRGBA[0] green: &lighterRGBA[1] blue: &lighterRGBA[2] alpha: &lighterRGBA[3]];
UIColor* lightest = [UIColor colorWithRed: (lighterRGBA[0] * 0.55 + 0.45) green: (lighterRGBA[1] * 0.55 + 0.45) blue: (lighterRGBA[2] * 0.55 + 0.45) alpha: (lighterRGBA[3] * 0.55 + 0.45)];
UIColor* darker = [UIColor colorWithRed: (tintRGBA[0] * 0.92) green: (tintRGBA[1] * 0.92) blue: (tintRGBA[2] * 0.92) alpha: (tintRGBA[3] * 0.92 + 0.08)];
CGFloat darkerRGBA[4];
[darker getRed: &darkerRGBA[0] green: &darkerRGBA[1] blue: &darkerRGBA[2] alpha: &darkerRGBA[3]];
UIColor* darkest = [UIColor colorWithRed: (darkerRGBA[0] * 0.65) green: (darkerRGBA[1] * 0.65) blue: (darkerRGBA[2] * 0.65) alpha: (darkerRGBA[3] * 0.65 + 0.35)];
//// Gradient Declarations
NSArray* gradientColors = [NSArray arrayWithObjects:
(id)lighter.CGColor,
(id)darker.CGColor, nil];
CGFloat gradientLocations[] = {0, 1};
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradientColors, gradientLocations);
//// top Drawing
UIBezierPath* topPath = [UIBezierPath bezierPathWithRect: CGRectMake(0, 0, rect.size.width, 1)];
[lightest setFill];
[topPath fill];
//// theGradient Drawing
UIBezierPath* theGradientPath = [UIBezierPath bezierPathWithRect: CGRectMake(0, 1, rect.size.width, rect.size.height - 1.0f)];
CGContextSaveGState(context);
[theGradientPath addClip];
CGContextDrawLinearGradient(context, gradient, CGPointMake(50, 1), CGPointMake(50, rect.size.height-1.0f), 0);
CGContextRestoreGState(context);
//// bottom Drawing
UIBezierPath* bottomPath = [UIBezierPath bezierPathWithRect: CGRectMake(0, rect.size.height-1.0f, rect.size.width, 1)];
[darkest setFill];
[bottomPath fill];
//// Cleanup
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
Thanks for the good question and the generous bounty. I went to work on this and neglected to check in to see that it was already answered acceptably. Nevertheless, it was fun building and testing the following navigation bar category, that reveals it's colors ...
//
// UINavigationBar+colors.h
#import <UIKit/UIKit.h>
#interface UINavigationBar (Colors)
// Answer an array of colors representing the color of the reciever, starting at fromY, up to toY
- (NSArray *)colorsFromY:(NSUInteger)fromY to:(NSUInteger)toY;
#end
Link with QuartzCore.framework.
//
// UINavigationBar+colors.m
#import "UINavigationBar+colors.h"
#import <QuartzCore/QuartzCore.h>
#define UIIMAGE_BYTES_PER_PIXEL 4u
#implementation UINavigationBar (Colors)
+ (NSData *)dataFromImage:(UIImage *)image {
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSUInteger dataSize = height * width * UIIMAGE_BYTES_PER_PIXEL;
unsigned char *rawData = malloc(dataSize);
NSUInteger bytesPerRow = width * UIIMAGE_BYTES_PER_PIXEL;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
NSData *rtn = [NSData dataWithBytes:rawData length:dataSize];
free(rawData);
return rtn;
}
+ (UIColor *)colorOfImage:(UIImage *)image atX:(NSUInteger)px atY:(NSUInteger)py {
NSData *imgData = [self dataFromImage:image];
if (!imgData) return nil;
NSUInteger byteIndex = UIIMAGE_BYTES_PER_PIXEL * (image.size.width * py + px);
unsigned char rgbaData[4];
NSRange range = { byteIndex, 4u };
[imgData getBytes:rgbaData range:range];
CGFloat red = rgbaData[0] / 255.0;
CGFloat green = rgbaData[1] / 255.0;
CGFloat blue = rgbaData[2] / 255.0;
CGFloat alpha = rgbaData[3] / 255.0;
return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}
- (UIImage *)asImage {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0.0);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
- (NSArray *)colorsFromY:(NSUInteger)fromY to:(NSUInteger)toY {
NSMutableArray *answer = [NSMutableArray array];
UIImage *image = [self asImage];
for (NSUInteger y = MAX(0, fromY); y < MIN(self.bounds.size.height, toY); y++) {
[answer addObject:[self.class colorOfImage:image atX:1 atY:y]];
}
return [NSArray arrayWithArray:answer];
}
#end
Call it like this:
// from a view controller contained by a navigation controller...
UINavigationBar *bar = self.navigationController.navigationBar;
NSArray *colors = [bar colorsFromY:0 to:bar.bounds.size.height];
for (UIColor *color in colors) {
NSLog(#"%#", color);
}
UIButton takes a single tintColor property but that doesn't mean it isn't computing other colors to use in the gradient behind the scenes. Try this tutorial.
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.-
I've got an MKAnnotation subclass representing a cluster of map pins, with the number of pins in the cluster retrievable from the MKAnnotation subclass. For these annotations, I would like to display a grey circle with a black bold number representing the number of pins in the cluster. I've made an MKAnnotationView subclass which implements initWithAnnotation:reuseIdentifier and drawRect: methods, and this is my implementation of the drawRect: method:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 0.7f, 0.7f, 0.7f, 0.5f);
CGContextFillEllipseInRect(context, rect);
UIFont *font = [UIFont boldSystemFontOfSize: [UIFont smallSystemFontSize]];
NSString *label = [NSString stringWithFormat:#"%i", [(LocationGroupAnnotation *)self.annotation locationCount]];
CGPoint labelLocation;
if ([label length] == 1)
{
labelLocation = CGPointMake(rect.size.width / 2.0f, (rect.size.height / 2.0f) - (font.capHeight / 2.0f));
} else if ([label length] == 2) {
labelLocation = CGPointMake(rect.size.width / 2.0f, (rect.size.height / 2.0f) - (font.capHeight / 2.0f));
} else {
labelLocation = CGPointMake(rect.size.width / 2.0f, (rect.size.height / 2.0f) - (font.capHeight / 2.0f));
}
[label drawAtPoint:labelLocation withFont:font];
NSLog(#"Drawn label at (%f,%f)", labelLocation.x, labelLocation.y);
}
Ignore the values for labelLocation in the if statement, I'm going to adjust that according to how much space each letter takes up so that the number is centered. What I am getting at the moment is a translucent grey circle, but no text. I assume the text is being drawn in the wrong location. Also how do I specify that the text should appear in front of the circle rather than behind it?
Right before calling drawAtPoint, set the color that you want the text in otherwise it uses the color set by the CGContextSetRGBFillColor call above:
[[UIColor blackColor] set]; //or some color that contrasts with background
[label drawAtPoint:labelLocation withFont:font];
If you draw the text after the circle, it should appear above the circle and vice versa.
Can someone help me create an index/count button for a UITableView, like this one?
iTunes http://img.skitch.com/20091107-nwyci84114dxg76wshqwgtauwn.preview.jpg
Is there an Apple example, or other tutorial? Thanks, Jordan
Wow... aaa... ok... I've got an easier way:
#import <QuartzCore/QuartzCore.h>
.....
UILabel *label = [[UILabel alloc] initWithFrame:
CGRectMake(cell.contentView.frame.size.width - 50, 0, 35, 35)];
label.layer.cornerRadius = 5;
label.backgroundColor = [UIColor blueColor]; //feel free to be creative
label.clipToBounds = YES;
label.text = #"7"; //Your text here
[cell.contentView addSubview: label];
[label release];
Basically, you're making a UILabel with rounded corners using the QuartzCore framework - don't forget to include it. Extra note: it only works on OS > 3.0.
You need to create a custom view, and then draw the oval and number in manually. Finally, assign that custom view as the accessory view of the cell. Here's the drawing code, using Core Graphics. It's not too tricky:
CGRect bounds = self.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();
float radius = bounds.size.height / 2.0;
NSString *countString = [NSString stringWithFormat: #"%d", _count];
if (_count < 100) bounds = CGRectMake(5, 0, bounds.size.width - 10, bounds.size.height);
CGContextClearRect(context, bounds);
CGContextSetFillColorWithColor(context, _color.CGColor);
CGContextBeginPath(context);
CGContextAddArc(context, radius + bounds.origin.x, radius, radius, M_PI / 2 , 3 * M_PI / 2, NO);
CGContextAddArc(context, (bounds.size.width + bounds.origin.x) - radius, radius, radius, 3 * M_PI / 2, M_PI / 2, NO);
CGContextClosePath(context);
CGContextFillPath(context);
[[UIColor whiteColor] set];
UIFont *font = [UIFont boldSystemFontOfSize: 14];
CGSize numberSize = [countString sizeWithFont: font];
bounds.origin.x += (bounds.size.width - numberSize.width) / 2;
[countString drawInRect: bounds withFont: font];