Online Book Reader

Home Category

iOS Recipes - Matt Drance [52]

By Root 237 0
elements to get the look you want. How can you do that and still allow the resulting image to be efficiently animated?

Solution

The hierarchy of UIViews allows us to layer multiple components to build up an image. We can create complex results by modifying the properties of each of the independent subviews. Once all of the UIViews are in place, we can then use a few lines of Core Graphics code to composite those UIViews into a single image.

As part of the Graphics Garden app, we use this technique to construct the flower image. We create the flower by using the basic elements we built in Recipe 23, Draw Gradient-Filled Bezier Paths . It consists of a ring of petals with a central smiley face and a short stem, with two additional petals shaded green to indicate leaves growing out from the stem.

This code constructs the composite UIView piece by piece from the component classes we have already created.

GraphicsGarden/PRPFlower.m

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;

CGRect smileRect = CGRectMake(halfWidth/2, halfHeight/4*.9,

halfWidth, halfHeight);

CGRect petalRect = CGRectMake(halfWidth-fullwidth/10, fullHeight/5,

fullwidth/5, fullwidth/2);

CGRect leafRect = CGRectMake(halfWidth-fullwidth/12, fullHeight*.84,

fullwidth/5, fullwidth/2);

CGRect stemRect = CGRectMake(halfWidth-fullwidth/8, halfHeight*1.3,

fullwidth/4, halfHeight*.8);

PRPStem *stem = [[PRPStem alloc] initWithFrame:stemRect];

stem.outerColor = [UIColor colorWithRed:0 green:.5 blue:0 alpha:1];

stem.innerColor = [UIColor colorWithRed:0.3 green:1 blue:.2 alpha:1];

[self addSubview:stem];

[stem release];

for (CGFloat i = M_PI/10; i < M_PI*2; i += M_PI/7.5) {

PRPetal *petal = [[PRPetal alloc] initWithFrame:petalRect];

petal.outerColor = [UIColor purpleColor];

petal.innerColor = [UIColor colorWithRed:1 green:0 blue:1 alpha:1];

[self addSubview:petal];

[petal release];

petal.layer.anchorPoint = CGPointMake(.5, 1);

petal.transform = CGAffineTransformMakeRotation(i);

}

for (CGFloat i = -M_PI/5; i < M_PI/5; i += M_PI/5*2) {

PRPetal *leaf = [[PRPetal alloc] initWithFrame:leafRect];

leaf.outerColor = [UIColor colorWithRed:0 green:.5 blue:0 alpha:1];

leaf.innerColor = [UIColor colorWithRed:0.3 green:1 blue:.2 alpha:1];

[self addSubview:leaf];

[leaf release];

leaf.layer.anchorPoint = CGPointMake(.5, 1);

leaf.transform = CGAffineTransformMakeRotation(i);

}

PRPSmile *smile = [[PRPSmile alloc] initWithFrame:smileRect];

smile.innerColor = [UIColor yellowColor];

smile.outerColor = [UIColor colorWithRed:1 green:.4 blue:0 alpha:1];

[self addSubview:smile];

[smile release];

To keep the process simple, we add the subviews, starting from the rearmost UIView, and build up the flower as each part is added. In this case, the stem is added first based on the PRPStem class. The outer ring of the flower is formed as each petal is added to the UIView, pointing up from the center, and transformed using CGAffineTransformMakeRotation with an incrementing angle of rotation (specified here as a fraction of Pi). The anchorPoint property is crucial here, because that defines the center of rotation for our transformation. The two leaves are then added using the same technique but with a much smaller range of rotation and an offset starting angle. Finally, the PRPSmile object is added to the UIView with its center set to match the center of rotation of the petals.

Now that we have the code to create the flower, we could use it to create all the flowers we need in our scene, but that would result in numerous UIViews. Apart from the large memory footprint, the total time needed to instantiate so many UIViews would be quite significant.

Only one PRPFLower object is created here, even though we are placing sixty flowers in our scene, because an image is created from that object using the new category method PRPCompositeView.

GraphicsGarden/MainViewController.m

PRPFlower *flower = [[PRPFlower alloc]

Return Main Page Previous Page Next Page

®Online Book Reader