Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
Improve your user experience through simple animation. Explore the fundamentals of iOS UIView animation as well as the building blocks of Core Animation - unlocking loads of versatility using very little code.
Updated Code Samples
Compatible with Xcode 8 & Swift 3
Links
Code - Before
- (IBAction)mute{
self.alpha = .25;
}
- (IBAction)delete{
[self removeFromSuperview];
}
- (IBAction)upgrade{
CGPoint from = self.center;
CGPoint to = CGPointMake(750, 584);//Plug for simplicity
self.layer.position = to;
CABasicAnimation *slide = [CABasicAnimation animationWithKeyPath:@"position"];
slide.fromValue = [NSValue valueWithCGPoint:from];
slide.toValue = [NSValue valueWithCGPoint:to];
slide.duration = 2.0;
[self.layer addAnimation:slide forKey:@"position"];
}
- (IBAction)flag{
UIImageView *flagView = [[UIImageView alloc]initWithFrame:CGRectMake(25, 15, 40, 40)];
[flagView setImage:[UIImage imageNamed:@"bombIcon"]];
[self addSubview:flagView];
}
Code - After
- (IBAction)mute{
[UIView animateWithDuration:1.0 delay:0.0 options:0 animations:^{
self.alpha = .25;
}completion:nil];
}
- (IBAction)delete{
CGPoint current = CGPointMake(self.frame.origin.x, self.frame.origin.y);
[self.layer setAnchorPoint:CGPointMake(0, 0)];
self.layer.position = current;
CABasicAnimation *swing = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
swing.fromValue = [NSNumber numberWithInt:0];
swing.toValue = [NSNumber numberWithInt:1.5];
swing.duration = 1.5;
swing.autoreverses = YES;
swing.repeatCount = 3;
swing.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.layer addAnimation:swing forKey:@"rotation"];
CABasicAnimation *drop = [CABasicAnimation animationWithKeyPath:@"position"];
CGPoint dropTo = CGPointMake(self.frame.origin.x, self.superview.frame.size.height);
drop.fromValue = [NSValue valueWithCGPoint:current];
drop.toValue = [NSValue valueWithCGPoint:dropTo];
drop.duration = 3.0;
drop.beginTime = CACurrentMediaTime() + 3.5;
[self.layer addAnimation:drop forKey:@"position"];
[self performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:6.5];
}
- (IBAction)upgrade{
CGPoint from = self.center;
CGPoint corner = CGPointMake(750, self.center.y);
CGPoint to = CGPointMake(750, 584);//Plug for simplicity
self.layer.position = to;
CAKeyframeAnimation *rightTurn = [CAKeyframeAnimation animationWithKeyPath:@"position"];
[rightTurn setValues:[NSArray arrayWithObjects:[NSValue valueWithCGPoint:from], [NSValue valueWithCGPoint:corner], [NSValue valueWithCGPoint:to], nil]];
rightTurn.duration = 2.0;
[self.layer addAnimation:rightTurn forKey:@"position"];
}
- (IBAction)flag{
CATextLayer *flagLayer = [CATextLayer layer];
flagLayer.position = CGPointMake(25, 20);
flagLayer.bounds = CGRectMake(0, 0, 30, 30);
flagLayer.backgroundColor = [[UIColor redColor] CGColor];
flagLayer.string = @"!";
flagLayer.fontSize = 24;
flagLayer.alignmentMode = @"center";
[self.bgView.layer addSublayer:flagLayer];
CABasicAnimation *pulse = [CABasicAnimation animationWithKeyPath:@"opacity"];
pulse.fromValue = [NSNumber numberWithFloat:1];
pulse.toValue = [NSNumber numberWithFloat:.2];
pulse.duration = 1.0;
pulse.autoreverses = YES;
pulse.repeatCount = HUGE_VALF;
[flagLayer addAnimation:pulse forKey:@"opacity"];
}
-
0:00
Now let's turn to our upgrade function.
-
0:02
As it stands,
-
0:03
we're using a CABasicAnimation to move the sticky diagonally from its
-
0:07
original position to the lowest empty spot on the high priority side of our screen.
-
0:12
Now the code should look pretty familiar to you.
-
0:15
We have to and from points, then use those as our to and
-
0:18
from values in an animation on the position key path.
-
0:22
Also, if this hard coded to position is setting off alarm bells, raise your hand.
-
0:27
Okay, good.
-
0:28
Now put your hand down because I can't see you.
-
0:31
In a real app, we would want to employ some reusable logic
-
0:33
to determine the destination, given any arrangement of the stickies, or
-
0:37
even use a more sophisticated super view class to handle the repositioning,
-
0:41
though here, we're just trying to illustrate how these animations work, so
-
0:44
I didn't want to confuse matters with that.
-
0:47
Now, the diagonal movement works, but I think it would look better
-
0:50
if it slides to the right, then down the high priority column.
-
0:53
More importantly,
-
0:54
it'll give us a perfect opportunity to try out CAKeyframe animations.
-
0:59
To do that, we'll need to use three points to act as our keyframes.
-
1:03
The from point, the to point, and that corner point
-
1:06
in the middle where we switch from horizontal to vertical movement.
-
1:09
That corner is pretty easy to figure out, as it shares an x-value with the to,
-
1:13
and a y-value with the from.
-
1:16
Now, we can create a CAKeyframeAnimation for position, and set the duration.
-
1:21
Next, we have to feed the animation an array of values, namely, our three points.
-
1:27
Lastly, we apply the animation to the layer.
-
1:39
Okay, that looks quite different.
-
1:42
The animation looked all right, but at the end,
-
1:44
the sticky snapped back to its original position.
-
1:47
That, of course, just won't do, and coincidentally,
-
1:49
is probably the number one mistake iOS animators make.
-
1:53
The reason this happens is that the animation is simply changing
-
1:56
the appearance of the layer.
-
1:58
The underlying position doesn't actually change.
-
2:00
The same would be true for other animated properties like opacity.
-
2:04
Just to repeat, and this is really important, the animation is changing
-
2:08
the appearance of the properties, but not the underlying values.
-
2:11
So when the animation ends,
-
2:13
the user again sees the actual original unchanged position.
-
2:18
Luckily, we can fix that pretty easily
-
2:20
by simply setting the actual position of the layer to the final key frame.
-
2:24
In this case, the point we called to.
-
2:27
Let's try it again.
-
2:37
There we go.
-
2:39
Now, because we gave our animation three key values but no key times,
-
2:44
core animation will default and assume that each leg of the animation, that is,
-
2:48
the journey between key frames, gets an equal chunk of the time to execute.
-
2:52
This works just fine, since the legs of our journey are more or
-
2:55
less the same size, but you could very easily give the animation an array of key
-
2:59
times to specify exactly how long each leg should take.
-
3:02
If you decide to do this, remember that you won't be specifying key times in
-
3:06
seconds, but rather in fractions of the total duration.
-
3:10
So for our example, the three key times would be 0, 0.5, and 1.
-
3:16
This brings us to your last animation, the flag.
-
3:19
Right now, we're just creating a little UIImageView,
-
3:22
filling it with the image of flag, and adding it as a sub-view to the sticky.
-
3:26
Instead, let's create a flag made up of a white exclamation point
-
3:30
on a red background, and then have that flag fade in and out continuously.
-
3:34
For this, we'll use one of those subclasses of CALayer we saw before,
-
3:39
specifically, CATextLayer.
-
3:42
We'll create a discreet CATextLayer called flagLayer.
-
3:46
We'll set its position and bounds, that's very important by the way.
-
3:49
Don't forget this part or it won't show up at all.
-
3:52
Set the background color, set the string, much like you would a UILabel,
-
3:57
the font size, the alignment mode, and then add it as a sub-layer.
-
4:01
You'll note here that we're adding it as a sub-layer on the bgView, and
-
4:05
that's because we want to make sure it appears on top of the image of the sticky,
-
4:09
which resides inside the bgView.
-
4:12
If we simply added it to self.layer It would appear in the sticky, but
-
4:16
behind the image of the yellow paper.
-
4:19
Next, we'll create a CABasicAnimation to handle the opacity change.
-
4:24
We'll set the fromValue to 1, the toValue to 0.2,
-
4:29
that's almost transparent We'll set the duration, the auto reverse to yes,
-
4:34
and the repeat count to HUGE_VALF, which is essentially a float proxy for
-
4:39
infinity, so it'll repeat over, and over, and over.
-
4:43
We add the animation, and we're ready to run it.
-
4:52
Voila, we see the CATextLayer created on the fly, and pulse in and out.
-
4:57
We can even delete the sticky, and watch the flag go along for the ride.
-
5:05
Today we've seen some of the simple yet
-
5:07
powerful things we can do with UI views and core animation.
-
5:10
We've used CA basic animations both individually and sequentially,
-
5:13
and also tried our hands at creating discreet CA layers on the fly.
-
5:17
We've also gotten tripped up by some of the common animation mistakes and
-
5:20
learn how to fix them.
-
5:21
If there's one thing I hope that you take away from this, is that the animation for
-
5:24
iOS is fairly simple to begin using, yet extremely dynamic.
-
5:28
You can get an incredible amount of variety and
-
5:30
have a lot of fun just using the basics I've shown today.
-
5:33
Start combining this functionalities and
-
5:35
scanning through the documentation, you'll find countless things to experiment with,
-
5:39
or better yet, ways to improve the apps you're working on right now.
-
5:43
I've added some links in the teacher's notes for
-
5:44
further reading if you're interested in learning more.
-
5:47
You'll also find the Objective C code we views today, along with both Swift 1.3 and
-
5:51
2.0 versions.
-
5:52
See you next time.
You need to sign up for Treehouse in order to download course files.
Sign up