Online Book Reader

Home Category

iOS Recipes - Matt Drance [50]

By Root 279 0
= CGPointMake(halfWidth, halfHeight*1.6);

CGPoint endPoint = CGPointMake(halfWidth, fullHeight);

CGPoint corner = CGPointMake(fullwidth, 0);

CGPoint leftCtrl = CGPointMake(-halfWidth, halfHeight/3);

CGPoint rightCtrl = CGPointMake(fullwidth*1.5, halfHeight/3);

UIBezierPath *pPath = [UIBezierPath bezierPath];

[pPath moveToPoint:startPoint];

[pPath addCurveToPoint:endPoint

controlPoint1:leftCtrl

controlPoint2:midPoint];

[pPath addCurveToPoint:startPoint

controlPoint1:midPoint

controlPoint2:rightCtrl];

[pPath addClip];

CGGradientRef gradient = [self gradientWithColor:self.innerColor

toColor:self.outerColor

count:3];

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextDrawLinearGradient(context,

gradient,

CGPointZero,

corner,

0);

pPath.lineWidth = self.lineThickness;

[self.strokeColor setStroke];

[pPath stroke];

}

Because the PRPetal class inherits from the base class PRPShapedView, we only need to override the drawRect: method. We build up the UIBezierPath from two cubic bezier curves that form the closed shape that we need to become a clipping Rect. The CGContextDrawLinearGradient function draws the gradient we created from the base class gradientWithColor method. Only then do we stroke the bezier path, clipping the gradient beneath it to match its shape.

GraphicsGarden/PRPSmile.m

- (void)drawRect:(CGRect)rect {

CGFloat halfHeight = self.bounds.size.height/2;

CGFloat halfWidth = self.bounds.size.width/2;

CGFloat fullHeight = self.bounds.size.height;

CGFloat fullwidth = self.bounds.size.width;

CGFloat radius = (halfWidth > halfHeight) ? halfHeight : halfWidth;

CGPoint midPoint = CGPointMake(halfWidth, halfHeight);

UIBezierPath *pPath = [UIBezierPath

bezierPathWithArcCenter: midPoint

radius: radius

startAngle: 0

endAngle: M_PI*2

clockwise: YES];

[pPath addClip];

CGGradientRef gradient = [self gradientWithColor:self.innerColor

toColor:self.outerColor

count:2];

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextDrawRadialGradient(context, gradient,

midPoint, 0,

midPoint, radius, 0);

pPath.lineWidth = self.lineThickness*1.7;

[self.strokeColor setStroke];

[pPath stroke];

// Eyes and Smile

[pPath removeAllPoints];

pPath.lineWidth = self.lineThickness;

[pPath moveToPoint:CGPointMake(halfWidth/2, halfHeight*1.3)];

[pPath addQuadCurveToPoint:CGPointMake(halfWidth*1.5, halfHeight*1.3)

controlPoint:CGPointMake(halfWidth, fullHeight*.91)];

[pPath stroke];

pPath = [UIBezierPath

bezierPathWithOvalInRect:CGRectMake(fullwidth/3-halfWidth*.1,

fullHeight/3,

halfWidth*.2,

halfHeight*.3)];

pPath.lineWidth = self.lineThickness;

[pPath fill];

[pPath stroke];

pPath = [UIBezierPath

bezierPathWithOvalInRect:CGRectMake(fullwidth/3*2-halfWidth*.1,

fullHeight/3,

halfWidth*.2,

halfHeight*.3)];

pPath.lineWidth = self.lineThickness;

[pPath fill];

[pPath stroke];

}

The PRPSmile class follows the pattern of the PRPetal class, except that we use an arc to draw a clipping circle, and we use the CGContextDrawRadialGradient function to create a radial gradient (colors radiate out from the center). The additional drawing code simply adds the eyes and smile to the graduated circle.

Now you have several views that you can use as building blocks for larger, more complex objects. In the next recipe, Recipe 24, Create Dynamic Images with Multiple Animations , that’s exactly what we’ll do.

Recipe 24 Create Dynamic Images with Multiple Animations

Problem

Core Animation simplifies the process of animating an object, making it move, rotate, or change size. But now you want to combine those techniques to create a more complex effect. Where do you start?

Solution

Making an object pulse and spin may not be something you need to do every day, but the technique here demonstrates how you can easily create complex effects by applying multiple animations to a single object (see Figure 30, Petals rotating and pulsing around the sun ).

GraphicsGarden/PRPSunshine.m

UIView *shineView = [[UIView alloc] initWithFrame:self.bounds];

self.shineLayer

Return Main Page Previous Page Next Page

®Online Book Reader