Custom alert view causes crash when iPad is rotated - ios

I am showing a custom alert view which is derived from UIAlertView in my view controller, and when I rotate the device for like 2-3 times, both the view controller and the alert view gets rotated. But then the app crashes with no clear clues. I have a breakpoint on All Exceptions but it can't catch it.
This crash is not happening if I use a standard UIAlertView. I found the custom alertview's code from someone else. Is there something misimplemented here? Or how can I get more clues of what's happening?
#implementation CustomAlertView
- (void) setBackgroundColor:(UIColor *) background
withStrokeColor:(UIColor *) stroke
{
if(fillColor != nil)
{
[fillColor release];
[borderColor release];
}
fillColor = [background retain];
borderColor = [stroke retain];
}
- (id)initWithFrame:(CGRect)frame
{
if((self = [super initWithFrame:frame]))
{
if(fillColor == nil)
{
}
}
return self;
}
- (void)layoutSubviews
{
for (UIView *sub in [self subviews])
{
if([sub class] == [UIImageView class] && sub.tag == 0)
{
// The alert background UIImageView tag is 0,
// if you are adding your own UIImageView's
// make sure your tags != 0 or this fix
// will remove your UIImageView's as well!
[sub removeFromSuperview];
break;
}
}
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
CGContextSetAllowsAntialiasing(context, true);
CGContextSetLineWidth(context, 0.0);
CGContextSetAlpha(context, 0.8);
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [borderColor CGColor]);
CGContextSetFillColorWithColor(context, [fillColor CGColor]);
// Draw background
CGFloat backOffset = 2;
CGRect backRect = CGRectMake(rect.origin.x + backOffset,
rect.origin.y + backOffset,
rect.size.width - backOffset*2,
rect.size.height - backOffset*2);
[self drawRoundedRect:backRect inContext:context withRadius:8];
CGContextDrawPath(context, kCGPathFillStroke);
// Clip Context
CGRect clipRect = CGRectMake(backRect.origin.x + backOffset-1,
backRect.origin.y + backOffset-1,
backRect.size.width - (backOffset-1)*2,
backRect.size.height - (backOffset-1)*2);
[self drawRoundedRect:clipRect inContext:context withRadius:8];
CGContextClip (context);
//Draw highlight
CGGradientRef glossGradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1.0, 1.0, 1.0, 0.35, 1.0, 1.0, 1.0, 0.06 };
rgbColorspace = CGColorSpaceCreateDeviceRGB();
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace,
components, locations, num_locations);
CGRect ovalRect = CGRectMake(-130, -115, (rect.size.width*2),
rect.size.width/2);
CGPoint start = CGPointMake(rect.origin.x, rect.origin.y);
CGPoint end = CGPointMake(rect.origin.x, rect.size.height/5);
CGContextSetAlpha(context, 1.0);
CGContextAddEllipseInRect(context, ovalRect);
CGContextClip (context);
CGContextDrawLinearGradient(context, glossGradient, start, end, 0);
CGGradientRelease(glossGradient);
CGColorSpaceRelease(rgbColorspace);
}
- (void) drawRoundedRect:(CGRect) rrect inContext:(CGContextRef) context
withRadius:(CGFloat) radius
{
CGContextBeginPath (context);
CGFloat minx = CGRectGetMinX(rrect), midx = CGRectGetMidX(rrect),
maxx = CGRectGetMaxX(rrect);
CGFloat miny = CGRectGetMinY(rrect), midy = CGRectGetMidY(rrect),
maxy = CGRectGetMaxY(rrect);
CGContextMoveToPoint(context, minx, midy);
CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
CGContextClosePath(context);
}
- (void)disableDismissForIndex:(int)index_{
canIndex = index_;
disableDismiss = TRUE;
}
- (void)dismissAlert{
[self dismissWithClickedButtonIndex:[self cancelButtonIndex] animated:YES];
}
- (void)vibrateAlert:(float)seconds{
canVirate = TRUE;
[self moveLeft];
[self performSelector:#selector (stopVibration) withObject:nil afterDelay:seconds];
}
-(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated {
if (disableDismiss == TRUE && canIndex == buttonIndex){
}else {
[super dismissWithClickedButtonIndex:buttonIndex animated:animated];
}
}
- (void)hideAfter:(float)seconds{
[self performSelector:#selector (dismissAlert) withObject:nil afterDelay:seconds];
}
- (void)moveRight{
if (canVirate){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.05];
self.transform = CGAffineTransformMakeTranslation(-10.0, 0.0);
[UIView commitAnimations];
[self performSelector:#selector (moveLeft) withObject:nil afterDelay:0.05];
}
}
- (void)moveLeft{
if (canVirate){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.05];
self.transform = CGAffineTransformMakeTranslation(10.0, 0.0);
[UIView commitAnimations];
[self performSelector:#selector (moveRight) withObject:nil afterDelay:0.05];
}
}
- (void)stopVibration{
canVirate = FALSE;
self.transform = CGAffineTransformMakeTranslation(0.0, 0.0);
}
#end

OK now I found it. In layoutViews method, replacing [sub removeFromSuperview]; line with ((UIImageView*)sub).image = nil; fixed the problem for me. Still I'm not sure about the exact reason though.

Related

how to delete content of UIView (Core Graphics)?

I'm trying to clear the content of what I have drawn when i press a button. But, I cant seem to do it figure out how to do it. I have google around abit and it seems like you need to do this inside of draw rect. This is the full code that I am using:
#import "PaintView.h"
#implementation PaintView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
hue = 0.0;
[self initContext:frame.size];
}
return self;
}
- (BOOL) initContext:(CGSize)size {
int bitmapByteCount;
int bitmapBytesPerRow;
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow = (size.width * 4);
bitmapByteCount = (bitmapBytesPerRow * size.height);
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
self.cacheBitmap = malloc( bitmapByteCount );
if (self.cacheBitmap == NULL){
return NO;
}
self.cacheContext = CGBitmapContextCreate (self.cacheBitmap, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
return YES;
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
[self drawToCache:touch];
}
- (void) drawToCache:(UITouch*)touch {
hue += 0.005;
if(hue > 1.0) hue = 0.0;
UIColor *color = [UIColor colorWithHue:hue saturation:0.7 brightness:1.0 alpha:1.0];
CGContextSetStrokeColorWithColor(self.cacheContext, [color CGColor]);
CGContextSetLineCap(self.cacheContext, kCGLineCapRound);
CGContextSetLineWidth(self.cacheContext, 6);
CGPoint lastPoint = [touch previousLocationInView:self];
CGPoint newPoint = [touch locationInView:self];
CGContextMoveToPoint(self.cacheContext, lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(self.cacheContext, newPoint.x, newPoint.y);
CGContextStrokePath(self.cacheContext);
CGRect dirtyPoint1 = CGRectMake(lastPoint.x-10, lastPoint.y-10, 20, 20);
CGRect dirtyPoint2 = CGRectMake(newPoint.x-10, newPoint.y-10, 20, 20);
[self setNeedsDisplayInRect:CGRectUnion(dirtyPoint1, dirtyPoint2)];
}
-(void)clear{
// this doesn't work.
CGContextClearRect(self.context, self.bounds);
}
- (void) drawRect:(CGRect)rect {
self.context = UIGraphicsGetCurrentContext();
CGImageRef cacheImage = CGBitmapContextCreateImage(self.cacheContext);
CGContextDrawImage(self.context, self.bounds, cacheImage);
CGImageRelease(cacheImage);
CGContextRetain(self.context);
}
#end
the button should call the view's setNeedsDisplay method which forces drawrect to be called or essentially forces a repaint.

How to get rotated image of imageview in uiview?

I created RotatedView subclass of UIView and added UIImageView as subview of RotatedView and also draw a image on RotatedView using drawRect: method same as image of imageView. I applied pinch and rotate gestures on imageView. When i pinch the imageView drawing image is also changed. But when i rotate the imageView, the drawing image is not changed. I used following code::
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor redColor];
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(80, 150, 100, 150)];
imageView.image = [UIImage imageNamed:#"Images_6.jpg"];
imageView.userInteractionEnabled = YES;
[self addSubview:imageView];
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotationMethod:)];
rotationGesture.delegate = self;
[imageView addGestureRecognizer:rotationGesture];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context =UIGraphicsGetCurrentContext();
CGRect rectFrame = CGRectMake(0, 0, imageView.frame.size.width, imageView.frame.size.height);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetLineWidth(context, 10.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 90, 0);
CGContextAddLineToPoint(context, 90, 90);
CGContextAddLineToPoint(context, 0, 90);
CGContextAddLineToPoint(context, 0, 0);
CGContextClip(context);
CGContextStrokePath(context);
CGContextDrawImage(context,rectFrame, imageView.image.CGImage);
}
-(void)rotationMethod:(UIRotationGestureRecognizer *)gestureRecognizer{
NSLog(#"rotationMethod");
if ([gestureRecognizer state]==UIGestureRecognizerStateBegan || [gestureRecognizer state]==UIGestureRecognizerStateChanged) {
CGAffineTransform transform = CGAffineTransformRotate(gestureRecognizer.view.transform, gestureRecognizer.rotation);
gestureRecognizer.view.transform = transform;
[gestureRecognizer setRotation:0];
}
[self setNeedsDisplay];
}
How do i get rotate image in UIView when the imageView is rotated?
**
Edited:
**
I got solution using first method. Now i am using second method. I think this is simple and best but I am not sure which one is best. In second method, image is rotated but not at center point. I am struggle to solve this problem. Please help me.
Modifying methods are:
- (void)drawRect:(CGRect)rect
{
NSLog(#"drawRect");
// Drawing code
CGContextRef context =UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetLineWidth(context, 10.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, imageRect.origin.x, imageRect.origin.y);
CGContextAddLineToPoint(context, imageRect.size.width, imageRect.origin.y);
CGContextAddLineToPoint(context, imageRect.size.width, imageRect.size.height);
CGContextAddLineToPoint(context, imageRect.origin.x, imageRect.size.height);
CGContextAddLineToPoint(context, imageRect.origin.x, imageRect.origin.y);
CGContextClip(context);
CGContextStrokePath(context);
CGContextDrawImage(context, imageRect, [self rotateImage:imageView.image].CGImage);
}
-(void)rotationMethod:(UIRotationGestureRecognizer *)gestureRecognizer{
NSLog(#"rotationMethod");
if ([gestureRecognizer state]==UIGestureRecognizerStateBegan || [gestureRecognizer state]==UIGestureRecognizerStateChanged) {
CGAffineTransform transform = CGAffineTransformRotate(gestureRecognizer.view.transform, gestureRecognizer.rotation);
gestureRecognizer.view.transform = transform;
lastRotation = gestureRecognizer.rotation;
[gestureRecognizer setRotation:0];
}
[self setNeedsDisplay];
}
- (UIImage *)rotateImage:(UIImage *) img
{
NSLog(#"rotateImage");
CGAffineTransform transform = imageView.transform;
transform = CGAffineTransformTranslate(transform, img.size.width, img.size.height);
transform = CGAffineTransformRotate(transform, lastRotation);
transform = CGAffineTransformScale(transform, -1, -1);
CGContextRef ctx = CGBitmapContextCreate(NULL, img.size.width, img.size.height,
CGImageGetBitsPerComponent(img.CGImage), 0,
CGImageGetColorSpace(img.CGImage),
CGImageGetBitmapInfo(img.CGImage));
CGContextConcatCTM(ctx, transform);
CGContextDrawImage(ctx, CGRectMake(20,20,img.size.width,img.size.height), img.CGImage);
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *newImg = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return newImg;
}
You need to use CGContextScaleCTM and CGContextRotateCTM (and possibly to appropriately transform your CGContextRef to match your UIImageView's transform.
Take a look at the Quartz 2D Programming Guide
Ok. Finally i got it using ANImageBitmapRep. I declared lastRotation, angle,rotateMe in RotatedView.h class.
-(void)rotationMethod:(UIRotationGestureRecognizer *)gestureRecognizer{
if ([gestureRecognizer state]==UIGestureRecognizerStateBegan) {
if (!rotateMe) {
rotateMe = [[ANImageBitmapRep alloc] initWithImage:displayImageView.image];
}else{
rotateMe =[ANImageBitmapRep imageBitmapRepWithImage:displayImageView.image];
}
}
CGFloat rotation = 0.0 - (lastRotation - [gestureRecognizer rotation]);
CGAffineTransform currentTransform = [gestureRecognizer view].transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[[gestureRecognizer view] setTransform:newTransform];
lastRotation = [gestureRecognizer rotation];
angle =lastRotation * (180 / M_PI);
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
CGRect imageRect = CGRectMake(0, 0, 90, 90);
// Drawing code
CGContextRef context =UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetLineWidth(context, 10.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, imageRect.origin.x, imageRect.origin.y);
CGContextAddLineToPoint(context, imageRect.size.width, imageRect.origin.y);
CGContextAddLineToPoint(context, imageRect.size.width, imageRect.size.height);
CGContextAddLineToPoint(context, imageRect.origin.x, imageRect.size.height);
CGContextAddLineToPoint(context, imageRect.origin.x, imageRect.origin.y);
CGContextClip(context);
CGContextStrokePath(context);
UIImage *rotatedImage1=[UIImage imageWithCGImage:[rotateMe imageByRotating:angle]];
CGContextDrawImage(context, imageRect, rotatedImage1.CGImage);
}
I find this solution. If anyone find best solution, give me suggestions according this problem.

How to remove corners for round rect bezier path

I am programming first time using Core Graphics, so don't have much idea that how exactly can I solve the problem.
I am drawing rounded rect bezier path along with gradient and stroke as background view for UITableviewCells. Everything has gone fine, except the extra black corners as shown in figure.
I haven't got any idea why they are showing and exactly what they are. Please can anyone help me? Thanks..
Code for creating cell
#import "CustomCellBackground.h"
.
.
.
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
cell.backgroundView = [[CustomCellBackground alloc] init];
cell.selectedBackgroundView = [[CustomCellBackground alloc]init];
}
// Configure the cell.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.backgroundColor = [UIColor clearColor];
return cell;
}
In CustomCellBackground.m
- (void)drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGPathRef path = [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:10.0] CGPath];
CGContextAddPath(context, path);
CGContextClip(context);
//CGContextSetLineJoin(context, kCGLineJoinRound);
drawLinearGradientWithFourColors(context, self.bounds);
CGContextSaveGState(context);
CGContextSetStrokeColorWithColor(context,[UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, 1.0);
CGContextAddPath(context, path);
CGContextStrokePath(context);
CGContextRestoreGState(context);
}
void drawLinearGradientWithFourColors(CGContextRef context, CGRect rect)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = {0.0, 0.2, 0.5, 1.0};
CGFloat colors[16] = {
85/255.0, 85/255.0, 85/255.0, 1.0,
45/255.0, 45/255.0, 45/255.0, 1.0,
22/255.0, 22/255.0, 22/255.0, 1.0,
0, 0, 0, 1.0
};
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 4);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
When you init your view , setOpaque parameter for layer of the view and view.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setOpaque:NO];
[self.layer setOpaque:NO];
}
return self;
}
I googled it and pasted the code below. For more info refer link:
Use below code:
typedef enum {
CustomCellBackgroundViewPositionTop,
CustomCellBackgroundViewPositionMiddle,
CustomCellBackgroundViewPositionBottom,
CustomCellBackgroundViewPositionSingle
} CustomCellBackgroundViewPosition;
#interface CustomCellBackgroundView : UIView {
UIColor *borderColor;
UIColor *fillColor;
CustomCellBackgroundViewPosition position;
}
#property(nonatomic, retain) UIColor *borderColor, *fillColor;
#property(nonatomic) CustomCellBackgroundViewPosition position;
#end
- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(c, [fillColor CGColor]);
CGContextSetStrokeColorWithColor(c, [borderColor CGColor]);
if (position == CustomCellBackgroundViewPositionTop) {
CGContextFillRect(c, CGRectMake(0.0f, rect.size.height - 10.0f, rect.size.width, 10.0f));
CGContextBeginPath(c);
CGContextMoveToPoint(c, 0.0f, rect.size.height - 10.0f);
CGContextAddLineToPoint(c, 0.0f, rect.size.height);
CGContextAddLineToPoint(c, rect.size.width, rect.size.height);
CGContextAddLineToPoint(c, rect.size.width, rect.size.height - 10.0f);
CGContextStrokePath(c);
CGContextClipToRect(c, CGRectMake(0.0f, 0.0f, rect.size.width, rect.size.height - 10.0f));
} else if (position == CustomCellBackgroundViewPositionBottom) {
CGContextFillRect(c, CGRectMake(0.0f, 0.0f, rect.size.width, 10.0f));
CGContextBeginPath(c);
CGContextMoveToPoint(c, 0.0f, 10.0f);
CGContextAddLineToPoint(c, 0.0f, 0.0f);
CGContextStrokePath(c);
CGContextBeginPath(c);
CGContextMoveToPoint(c, rect.size.width, 0.0f);
CGContextAddLineToPoint(c, rect.size.width, 10.0f);
CGContextStrokePath(c);
CGContextClipToRect(c, CGRectMake(0.0f, 10.0f, rect.size.width, rect.size.height));
} else if (position == CustomCellBackgroundViewPositionMiddle) {
CGContextFillRect(c, rect);
CGContextBeginPath(c);
CGContextMoveToPoint(c, 0.0f, 0.0f);
CGContextAddLineToPoint(c, 0.0f, rect.size.height);
CGContextAddLineToPoint(c, rect.size.width, rect.size.height);
CGContextAddLineToPoint(c, rect.size.width, 0.0f);
CGContextStrokePath(c);
return; // no need to bother drawing rounded corners, so we return
}
// At this point the clip rect is set to only draw the appropriate
// corners, so we fill and stroke a rounded rect taking the entire rect
CGContextBeginPath(c);
addRoundedRectToPath(c, rect, 10.0f, 10.0f);
CGContextFillPath(c);
CGContextSetLineWidth(c, 1);
CGContextBeginPath(c);
addRoundedRectToPath(c, rect, 10.0f, 10.0f);
CGContextStrokePath(c);
}
static void addRoundedRectToPath(CGContextRef context, CGRect rect,
float ovalWidth,float ovalHeight)
{
float fw, fh;
if (ovalWidth == 0 || ovalHeight == 0) {// 1
CGContextAddRect(context, rect);
return;
}
CGContextSaveGState(context);// 2
CGContextTranslateCTM (context, CGRectGetMinX(rect),// 3
CGRectGetMinY(rect));
CGContextScaleCTM (context, ovalWidth, ovalHeight);// 4
fw = CGRectGetWidth (rect) / ovalWidth;// 5
fh = CGRectGetHeight (rect) / ovalHeight;// 6
CGContextMoveToPoint(context, fw, fh/2); // 7
CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);// 8
CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);// 9
CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);// 10
CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // 11
CGContextClosePath(context);// 12
CGContextRestoreGState(context);// 13
}

Fast way to redraw gradient?

I need to draw (a bit) complex gradients programmatically. Here is my params.
#define SHADOW_OPACITY 0.35
const size_t num_locations = 4;
const CGFloat locations[num_locations] = { 0, 0.12, 0.42, 1.0 };
const CGFloat components[num_locations * 2] = { 0.0, 1.0 * SHADOW_OPACITY,
0.0, 1.0 * SHADOW_OPACITY,
0.0, 0.73 * SHADOW_OPACITY,
0.0, 0.0 };
Three rings with opacity and a dashed ring inside. All works just fine.
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
[self drawGradientInContext:context];
CGContextSetLineWidth(context, CIRCLE_STROKE_WIDTH);
CGContextBeginPath(context);
CGFloat dashLength = DASH_LENGTH(self.circleRadius);
CGFloat dashArray[] = { dashLength, dashLength };
CGContextSetLineDash(context, 0, dashArray, 2);
CGContextAddArc(context, CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds), self.circleRadius, 0, 2 * M_PI, YES);
CGContextClosePath(context);
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
CGContextDrawPath(context, kCGPathStroke);
}
- (void)drawGradientInContext:(CGContextRef)context
{
self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorspace, components, locations, num_locations);
CGPoint gradientCenter = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
CGContextDrawRadialGradient(context,
gradient,
gradientCenter,
self.circleRadius - 1,
gradientCenter,
self.circleRadius + SHADOW_WIDTH,
kCGGradientDrawsAfterEndLocation);
CGColorSpaceRelease(colorspace);
CGGradientRelease(gradient);
}
Well, I need to apply zoom.
- (void)zoom:(UIPinchGestureRecognizer *)sender
{
effectiveScale = beginGestureScale * sender.scale;
self.circleRadius = effectiveScale * BASE_RADIUS;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]]) {
beginGestureScale = effectiveScale ? effectiveScale : 1.0;
}
return YES;
}
Well, since that things are screwed up: it glitches as the hell!
What could I do there?

Draw error on retina screen

I am working on "drawing" project.My project works well on screen. But when i test it on retina screen so i got an image like this retina screen!
It works on ipad2 very well.
some part of my code:
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
[curImage drawAtPoint:CGPointMake(0, 0)];
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
if(previousPoint1.x == previousPoint2.x && previousPoint1.y == previousPoint2.y && previousPoint1.x == currentPoint.x && previousPoint1.y == currentPoint.y)
{
CGContextSetLineCap(context, kCGLineCapRound);
}
else
{
CGContextSetLineCap(context, kCGLineCapRound);
}
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextSetShouldAntialias(context, YES);
CGContextSetAllowsAntialiasing(context, YES);
CGContextSetFlatness(context, 0.1f);
CGContextSetAlpha(context, self.lineAlpha);
CGContextStrokePath(context);
- (void) calculateMinImageArea:(CGPoint)pp1 :(CGPoint)pp2 :(CGPoint)cp{
CGPoint mid1 = midPoint(pp1, pp2);
CGPoint mid2 = midPoint(cp, pp1);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, pp1.x, pp1.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(path);
CGPathRelease(path);
CGRect drawBox = bounds;
//Pad our values so the bounding box respects our line width
drawBox.origin.x -= self.lineWidth * 1;
drawBox.origin.y -= self.lineWidth * 1;
drawBox.size.width += self.lineWidth * 2;
drawBox.size.height += self.lineWidth * 2;
UIGraphicsBeginImageContext(drawBox.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
curImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self setNeedsDisplayInRect:drawBox];
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
CGPoint midPoint(CGPoint p1, CGPoint p2)
{
return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);}

Resources