Let’s make the yellow
LittleView
in the
previous project
travel under its own power,
without being dragged.
Remove the three methods
touchesBegan:withEvent:
,touchesMoved:withEvent:
,touchesEnded:withEvent:
View
.
Replace them with the following
touchesBegan:withEvent
.
Then click on the big white
View
to attract the little yellow
LittleView
.
A
block
is a group of statements surrounded by
^{
}
.
It’s like an anonymous function.
The last two arguments of
animateWithDuration:delay:options:animations:completion:
can be blocks.
Write
NULL
if there’s no block that needs to be executed.
//Animation in iOS 4, 5, 6, and 7 - (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event { [UIView animateWithDuration: 1.0 delay: 0.0 options: UIViewAnimationOptionCurveEaseInOut animations: ^{ //This block describes what the animation should do. littleView.center = [[touches anyObject] locationInView: self]; } completion: NULL ]; }
The group of statements between the calls to
beginAnimations:context:
and
commitAnimations
is called the
animation block.
Please indent the animation block
to make it more conspicuous,
and to ensure that the calls to
beginAnimations:context:
and
commitAnimations
are paired up correctly.
Look at the
four
possible arguments
for
setAnimationCurve:
.UIViewAnimationCurveEaseInOut
,
starts and ends slowly but is fast in the middle.
See an example here.
//Animation in iOS 3. - (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event { [UIView beginAnimations: nil context: NULL]; //Describe the animation itself. [UIView setAnimationDuration: 1.0]; //in seconds; default is 0.2 [UIView setAnimationCurve: UIViewAnimationCurveEaseInOut]; [UIView setAnimationRepeatCount: 1.0]; //The default is 1.0. //Describe what the animation should do. littleView.center = [[touches anyObject] locationInView: self]; [UIView commitAnimations]; }
LittleView
’s
yellowColor
to
clearColor
.
center
.
[UIView setAnimationRepeatCount: 2];Then go back to 1.
UIViewAnimationOptionCurveEaseInOutto the following. Use the “bitwise or” operator
|
to combine the options together.
UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState
LittleView
’s position.
Now animate a change to the
LittleView
’s opacity.
Insert the following statement after we assign a value to
littleView.center
.
This demonstrates that we can animate
the position and the opactity simultaneously.
littleView.alpha = 0.0; //0.0 is transparent, 1.0 is opaqueThen click on the white area and watch the
LittleView
fade out.
You can now give the cloaking device to your
Romulan
warship.
Give class
View
an instance variable of type
BOOL
.
Initalize it to
YES
in the
initWithFrame:
method of
View
,
and flip its value in the
touchesBegan:withEvent:
method of class
View
.
Then let the animation change the
LittleView
’s
alpha level to 1 if the instance variable is
YES
,
and to 0 if the instance variable is
NO
.
LittleView
’s
backgroundColor
.
Remove the code that animates the opacity change.
I wish we could replace it by the following.
littleView.backgroundColor = [UIColor greenColor];Then click on the white area. The
LittleView
animates gradually to green in iOS 4,
but turns green instantaneously in iOS 5, 6, and 7.
One way to make it animate gradually in 5, 6, and 7
is to remove the
drawRect:
method from class
LittleView
.
But no one wants to do that.
A better way to make it animate in iOS 5, 6, and 7 is to keep the
drawRect:
method in
LittleView
and add the following chunks of code to the project.
A
UIView
is built on top of a
Core Animation
CALayer
.
We’ll make the
LittleView
transparent so we can see the
layer
underneath it.
In the
initWithFrame:
method of
LittleView
,
//self.backgroundColor = [UIColor yellowColor]; self.backgroundColor = [UIColor clearColor]; CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); const CGFloat components[] = {1.0, 1.0, 0.0, 1.0}; //rgba CALayer *layer = self.layer; layer.backgroundColor = CGColorCreate(colorspace, components);
In the
touchesBegan:withEvent:
method of class
View
,
[UIView animateWithDuration: 1.0 delay: 0.0 options: UIViewAnimationOptionCurveEaseInOut animations: ^{ //This block describes what the animation should do. littleView.center = [[touches anyObject] locationInView: self]; CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); const CGFloat components[] = {0.0, 1.0, 0.0, 1.0}; littleView.layer.backgroundColor = CGColorCreate(colorspace, components); } completion: NULL ];
completion:
argument does not have to be
NULL
.
You can launch a second animation when the first animation has completed.
[UIView animateWithDuration: 1.0 delay: 0.0 options: UIViewAnimationOptionCurveEaseInOut animations: ^{ //This block describes what the animation should do. littleView.center = [[touches anyObject] locationInView: self]; } completion: ^(BOOL b) { [UIView animateWithDuration: 1.0 delay: 0.0 options: UIViewAnimationOptionCurveEaseInOut animations: ^{ //This block describes what the animation should do. littleView.center = //another CGPoint; } completion: NULL ]; } ];
LittleView
’s
scale (size).
Insert the following into the block.
littleView.transform = CGAffineTransformMakeScale(1, 2);Then click on the white area and watch the height of the
LittleView
double.
LittleView
’s
orientation.
Remove the code that animates the scale,
and replace it by the following.
Multiplication by π/180
converts
degrees
to
radians.
littleView.transform = CGAffineTransformMakeRotation(90 * M_PI / 180);Then click on the white area and watch the
LittleView
tumble 90° clockwise.
Can you rotate counterclockwise?
CGAffineTransform
is a structure, not an object,
so it can be stored in a variable.
CGAffineTransform s = CGAffineTransformMakeScale(1, 2); CGAffineTransform r = CGAffineTransformMakeRotation(90 * M_PI / 180); CGAffineTransform c = CGAffineTransformConcat(r, s); littleView.transform = c;Of course, you can telescope the above lines to
CGAffineTransform s = CGAffineTransformMakeScale(1, 2); CGAffineTransform r = CGAffineTransformMakeRotation(90 * M_PI / 180); littleView.transform = CGAffineTransformConcat(r, s);or even to
littleView.transform = CGAffineTransformConcat( CGAffineTransformMakeRotation(90 * M_PI / 180), CGAffineTransformMakeScale(1, 2) );
center
,
alpha
,
backgroundColor
,
and
transform
properties of a
UIView
.
See the
short
list
and
long
list
of animatable properties.