Rotating the Object
In this section, how to rotate a view (in this case, turn the car around). To do so, you update the rotate code stub with the bolded code in Listing-4.
Listening-4: Updating rotate
- (void)rotate { CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI); void (^animation)() = ^(){ car.transform = transform; }; void (^completion)(BOOL) = ^(BOOL finished){ [self returnCar]; }; [UIView animateWithDuration:3 animations:animation completion:completion]; }
This method uses the block declarations that explain in the previous section. The CGAffineTransform data structure represents a matrix used for affine transformations - how points in one coordinate system map to points in another coordinate system. Although CGAffineTransform has a number of uses (such as scaling and translating a coordinate system ), the only one covered here is the rotation method you used in Listing-4.
CGAffineTransformMakeRotation(M_PI)
To rotate a view, you specify the angle, in radians, to rotate the coordinate system axes. Whereas degrees are numbers between 0 and 360, radians, though similar, range from 0 to 2*pi. So, when you create a rotation that turns an object around one half-circle, that rotation in radians is pi (M_PI is a system constant that represents pi).
Tip:
Just to make your life interesting, you should note that in iOS, positive is counterclockwise but on Mac OS X, positive is clockwise.
The end result is that the car will rotate 180 degrees in three seconds, and when it is done, you send the returnCar message in the completion handler. To return the car back to its original position, add the bolded code in Listing-5 to the returnCar method stub in RTViewController.m.
Listing-5: Updating returnCar
- (void)returnCar { CGPoint center = CGPointMake(car.center.x, self.view.frame. origin.y + self.view.frame.size.height - car. frame.size.height/2 ); void (^animation)() = ^(){ car.center = center; }; void (^completion)(BOOL) = ^(BOOL finished){ [self continueRotation]; }; [UIView animateWithDuration:3 animations:animation completion:completion]; }
This approach is pretty much the same as that of the testDrive method except that the new center is back where the car started. You put the center back by computing the bottom of the view:
self.view.frame.origin.x + self.view.frame.size.height
and then subtracting half the car's height, as shown in Listing-5.
But you're not done yet. You need to rotate the car back to its original position (unless you want to drive in reverse from California to New York). Add the bolded code in Listing 10-6 to the continueRotation method stub in RTViewController.m.
Listing-6: Updating continueRotation
- (void)continueRotation { CGAffineTransform transform = CGAffineTransformMakeRotation(0); void (^animation)() = ^(){ car.transform = transform; }; [UIView animateWithDuration:3 animations:animation completion:nil]; }
You need to understand that the transform is still there; that is, you created a transform to rotate the car 180 degrees. If you want to get the car back to the original position, you need to return the transform to 0.
You could extend this action by having the car drive around the perimeter of the screen.