What's the fastest way to create a transparent line in UIKit? - iphone

This one:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, y, width, 1)];
view.backgroundColor = [UIColor whiteColor];
view.alpha = 0.1;
or this one:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, y, width, 1)];
view.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.1];
or is there any third alternative? Using a UIImageView with image? Doing custom drawing with CoreGraphics? What is supposed to be fastest?

The fastest way would be to create a CALayer. Using this will allow you to easily alter its color/opacity if needed.
CALayer *line = [CALayer new];
line.frame = CGRectMake(x, y, width, 1.0);
line.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.1].CGColor;
[someView.layer addSublayer:line];
If you want to draw a line right onto an existing view and have it stay there with no altering you can add the following code to the drawRect: method of the existing view:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] colorWithAlphaComponent:0.1].CGColor);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, x, y);
CGContextAddLineToPoint(context, x + width, y);
CGContextStrokePath(context);

Related

Draw Vertical line in UIView

UIView * lineView = [[UIView alloc] initWithFrame:CGRectMake(0, dialogContainer.bounds.size.height - buttonHeight - buttonSpacerHeight, dialogContainer.bounds.size.width, buttonSpacerHeight)];
lineView.backgroundColor = [UIColor colorWithRed:198.0/255.0 green:198.0/255.0 blue:198.0/255.0 alpha:1.0f];
[dialogContainer addSubview:lineView];
I have used this code to draw horizontal line on UIView. How can I add Vertical line to UIView?
UIView * lineView = [[UIView alloc] initWithFrame:CGRectMake(dialogContainer.bounds.size.width/2, 0, buttonSpacerHeight, dialogContainer.bounds.size.height)];
lineView.backgroundColor = [UIColor colorWithRed:198.0/255.0 green:198.0/255.0 blue:198.0/255.0 alpha:1.0f];
[dialogContainer addSubview:lineView];
You can subclass UIView and override the drawRect: method. For example
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
//Horizontal Line
CGContextSetLineWidth(context, buttonSpacerHeight);
CGContextMoveToPoint(context,0,dialogContainer.bounds.size.height - buttonHeight - buttonSpacerHeight);
CGContextAddLineToPoint(context,dialogContainer.bounds.size.height - buttonHeight - buttonSpacerHeight + dialogContainer.bounds.size.width,dialogContainer.bounds.size.height - buttonHeight - buttonSpacerHeight);
//Vertical Line
CGContextAddLineToPoint(context,dialogContainer.bounds.size.height - buttonHeight - buttonSpacerHeight + dialogContainer.bounds.size.width, dialogContainer.bounds.size.height);
CGContextStrokePath(context);
}
If you are adamant to use UIViews itself to draw vertical lines then reduce the width to a negligible value and increase the height of the UIView according to your wish.
Just exchange your height and width to draw vertical line simple :)
UIView * lineView = [[UIView alloc] initWithFrame:CGRectMake(0, dialogContainer.bounds.size.height - buttonHeight - buttonSpacerHeight,buttonSpacerHeight, dialogContainer.bounds.size.height)];
other example
UIView *horizontalLineView=[[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 2)];
[horizontalLineView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:horizontalLineView];
UIView *verticalLineView=[[UIView alloc] initWithFrame:CGRectMake(100, 100, 2, 100)];
[verticalLineView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:verticalLineView];
If you want to use coreGraphic then
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, self.frame);
CGContextMoveToPoint(context, XstartPoint, ystartPoint);
CGContextAddLineToPoint(context,XendPoint,YendPoint);
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);
CGContextStrokePath(context);
}
If you want to draw using sprite kit then follow
taking Benny's answer to swift, you could do something like:
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
let spacerHeight = rect.size.height
CGContextSetLineWidth(context, 2.0)
CGContextMoveToPoint(context, 0, (spacerHeight / 4.0))
CGContextAddLineToPoint(context, 0, 3 * (spacerHeight / 4.0))
CGContextSetStrokeColorWithColor(context, UIColor.whiteColor().CGColor)
CGContextStrokePath(context)
}
According to Apple's documentation CGRect Returns a rectangle with the specified coordinate and size values:
CGRect CGRectMake (
CGFloat x,
CGFloat y,
CGFloat width,
CGFloat height
);
So try inverting what you ised to have as the width with the height
Like you have draw horizontal line just increase the height of UIView and and decrease the width like the below,
UIView * lineView = [[UIView alloc] initWithFrame:CGRectMake(0, dialogContainer.bounds.size.height - buttonHeight - buttonSpacerHeight, 2, 200)];

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.-

Two-color background for UILabel

I got a requirements to display a UILabel with background split between two colors, like in this image:
(colors here are black at the bottom and 50% gray at the top - but this is not important). I tried setting the label's background colour to 50% grey in the interface builder and then do this in the code:
CALayer *sl1 = [[[CALayer alloc] init] autorelease];
sl1.frame = CGRectMake(0, lbl.frame.size.height / 2, lbl.frame.size.width, score1.frame.size.height/2);
sl1.backgroundColor = [[UIColor blackColor] CGColor];
[lbl.layer insertSublayer:sl1 atIndex:0];
Unfortunately, this resulted in the black part being drawn over the text, so the label looks like this:
which is, needless to say, is not something I need. So how can I get this background without turning to custom images? The issue is I need to have UILabel's like this in several places, different sizes - so I would need to create multiple versions of the background image.
Any ideas? Thanks.
this works:
UILabel* myLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 50)];
myLabel.text = #"Ciao";
myLabel.textColor = [UIColor greenColor];
UIGraphicsBeginImageContext(CGSizeMake(100, 50));
CGContextRef context = UIGraphicsGetCurrentContext();
// drawing with a gray fill color
CGContextSetRGBFillColor(context, 0.4, 0.4, 0.4, 1.0);
// Add Filled Rectangle,
CGContextFillRect(context, CGRectMake(0.0, 0.0, 100, 50));
// drawing with a black fill color
CGContextSetRGBFillColor(context, 0., 0., 0., .9);
// Add Filled Rectangle,
CGContextFillRect(context, CGRectMake(0.0, 25, 100, 25));
UIImage* resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
myLabel.backgroundColor = [UIColor colorWithPatternImage:resultingImage];
[self.view addSubview:myLabel];
Use UIColor's +colorWithPatternImage:. Pass in a 1px by the UILabel's height image and it will be "tiled" across the the width of the view.
myLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"label-background.png"]];
first you have to subclass the UILabel and override it's drawRect: method like this for gradient background
- (void)drawRect:(CGRect)rect
{
//////////////GET REFERENCE TO CURRENT GRAPHICS CONTEXT
CGContextRef context = UIGraphicsGetCurrentContext();
//////////////CREATE BASE SHAPE WITH ROUNDED CORNERS FROM BOUNDS
CGRect activeBounds = self.bounds;
CGFloat cornerRadius = 10.0f;
CGFloat inset = 6.5f;
CGFloat originX = activeBounds.origin.x + inset;
CGFloat originY = activeBounds.origin.y + inset;
CGFloat width = activeBounds.size.width - (inset*2.0f);
CGFloat height = activeBounds.size.height - (inset*2.0f);
CGRect bPathFrame = CGRectMake(originX, originY, width, height);
CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:bPathFrame cornerRadius:cornerRadius].CGPath;
//////////////CREATE BASE SHAPE WITH FILL AND SHADOW
CGContextAddPath(context, path);
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:210.0f/255.0f green:210.0f/255.0f blue:210.0f/255.0f alpha:1.0f].CGColor);
CGContextSetShadowWithColor(context, CGSizeMake(0.0f, 1.0f), 6.0f, [UIColor colorWithRed:0.0f/255.0f green:0.0f/255.0f blue:0.0f/255.0f alpha:1.0f].CGColor);
CGContextDrawPath(context, kCGPathFill);
//////////////CLIP STATE
CGContextSaveGState(context); //Save Context State Before Clipping To "path"
CGContextAddPath(context, path);
CGContextClip(context);
//////////////DRAW GRADIENT
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
size_t count = 3;
CGFloat locations[3] = {0.0f, 0.57f, 1.0f};
CGFloat components[12] =
{ 0.0f/255.0f, 0.0f/255.0f, 0.0f/255.0f, 1.0f, //1
5.0f/255.0f, 5.0f/255.0f, 5.0f/255.0f, 1.0f, //2
10.0f/255.0f, 10.0f/255.0f, 10.0f/255.0f, 1.0f}; //3
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, count);
CGPoint startPoint = CGPointMake(activeBounds.size.width * 0.5f, 0.0f);
CGPoint endPoint = CGPointMake(activeBounds.size.width * 0.5f, activeBounds.size.height);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGColorSpaceRelease(colorSpace);
CGGradientRelease(gradient);
}
This will draw black to white gradient background
May this will help you
Happy Codding :)
the above code is from this site http://mobile.tutsplus.com/tutorials/iphone/ios-sdk-uialertview-custom-graphics/

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

Drawing a transparent circle on top of a UIImage - iPhone SDK

I am having a lot of trouble trying to find out how to draw a transparent circle on top of a UIImage within my UIImageView. Google-ing gives me clues, but I still can't find a working example.
Are there any examples that anyone knows of that demonstrate this?
Easiest way is simply to create a semi-transparent square UIView, then set the cornerRadius of its layer to be half of its width/height. Something like:
UIView *squareView = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];
squareView.alpha = 0.5;
squareView.layer.cornerRadius = 50;
...
[squareView release];
This has got to be the simplest solution:
CGFloat r = 150;
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0,0,1.5*r,1.5*r)];
lbl.text = #"●";
lbl.transform = CGAffineTransformMakeTranslation(0.0f, -r/6);
lbl.textAlignment = UITextAlignmentCenter;
lbl.backgroundColor = [UIColor clearColor];
lbl.textColor = [UIColor redColor];
lbl.font = [UIFont systemFontOfSize:2*r];
lbl.alpha = 0.5;
lbl.center = self.view.center;
[self.view addSubview:lbl];
One way would be to add a CAShapeLayer with a circular path, either directly to the layer of the UIImageView or as the layer of a new UIView that is added to the UIImageView.
If you actually want to modify the image, then create a mutable copy of it by drawing it into a CGBitmapContext then creating a new image from the modified bitmap.
CGPathRef circlePath = CGPathCreateMutable();
CGPathAddEllipseInRect( circlePath , NULL , CGRectMake( 0,0,20,20 ) );
CAShapeLayer *circle = [[CAShapeLayer alloc] init];
circle.path = circlePath;
circle.opacity = 0.5;
[myImageView.layer addSublayer:circle];
CGPathRelease( circlePath );
[circle release];
You can implement a custom sub-class of UIView that draws your image and then the circle in the drawRect method:
#interface CircleImageView : UIView {
UIImage * m_image;
CGRect m_viewRect;
// anything else you need in this view?
}
Implementation of drawRect:
- (void)drawRect:(CGRect)rect {
// first draw the image
[m_image drawInRect:m_viewRect blendMode:kCGBlendModeNormal alpha:1.0];
// then use quartz to draw the circle
CGContextRef context = UIGraphicsGetCurrentContext ()
// stroke and fill black with a 0.5 alpha
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 0.5);
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 0.5);
// now draw the circle
CGContextFillEllipseInRect (context, m_viewRect);
}
You will need to set up the m_viewRect and m_image member functions on init.