Sequence of affine transformation with Quartz 2D - ios

I'm attempting to simulate the incorrect password entry animation in OS X with an UIAlertView in iOS. Essentially I want it to translate the alert left then translate right. Here is what I am doing:
[UIView animateWithDuration:0.5
animations:^{
alertView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 200, 0);
alertView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, -200, 0);
}];
This doesn't have the desired effect however. The alert shoots of to the right instantaneously and then smoothly translates to the left. How can I get both of the translations to occur smoothly after each other?

Try this:
[UIView animateWithDuration:0.5 animations:^{
alertView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 200, 0);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 animations:^{
alertView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, -200, 0);
}];
}];
But I would do the animation like this:
[UIView animateWithDuration:0.1 animations:^{
alertView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 20, 0);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
alertView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, -20, 0);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
alertView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 0, 0);
}];
}];
}];
Up to you! ;-)

Related

How to animate an UILabel from small to its original size?

Actually i am using RESlider in my app. In the menu table view there is a profile image and aside to it there is a notification label. Now i want is that when the user presses the hamburger menu the notification label(orange label with 999 number) should animate from a tiny dot to its original size. How to achieve this??
Put this in viewDidAppear
-(void)viewDidAppear:(BOOL)animated{
self.label.transform = CGAffineTransformMakeScale(0.01, 0.01);
[UIView animateWithDuration:0.5 animations:^{
self.label.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
}];
}
myTextLabel.transform = CGAffineTransformMakeScale(0.3, 0.3);
[UIView animateWithDuration:2.0
delay: 0.1
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
myTextLabel.transform = CGAffineTransformMakeScale(1.5, 1.5); //grow
}
completion:^(BOOL finished){
myTextLabel.transform = CGAffineTransformMakeScale(1, 1);
}];
Change the transform scale of your label, like this :
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut
animations:^{
timerLabel.transform = CGAffineTransformScale(timerLabel.transform, 0.7, 0.7);
}
completion:nil];

How to do text field shake effect?

I'm trying to imitate the effect at login in Mac OSX: when you put a wrong password the textfield begin a nice shake effect. I tried this but I'm not satisfied.
-(void)shakeText:(UITextField*)textField
{
[UIView animateWithDuration:0.25
delay:0.0
options:UIViewAnimationOptionAutoreverse
animations:^{textField.transform =CGAffineTransformMakeTranslation(5, 0);}
completion:^(BOOL finished) {
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionAutoreverse
animations:^{textField.transform = CGAffineTransformMakeTranslation(5, 0);}
completion:nil];
}];
}
Is there a function in iOS to do it properly?
Please try the following code:
// Change the 10 & -10 values as you wish
CGAffineTransform leftWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(-10.0));
CGAffineTransform rightWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(10.0));
textField.transform = leftWobble;
[UIView animateWithDuration:0.25
delay:0
options:(UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse) animations:^{
[UIView setAnimationRepeatCount:6]; // Change this value as you want
textField.transform = rightWobble;
} completion:^(BOOL finished){
textField.transform = CGAffineTransformIdentity;
}];

When creating an animation to cause a UIImageView to go up and down (almost float) infinitely, how do I stop a pause at the end of the animation?

Here's the code I'm using to take a UIImageView and make it float up and down.
[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionRepeat animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.25 animations:^{
self.slider.transform = CGAffineTransformMakeTranslation(0, -5.0);
}];
[UIView addKeyframeWithRelativeStartTime:0.25 relativeDuration:0.5 animations:^{
self.slider.transform = CGAffineTransformMakeTranslation(0, 5.0);
}];
[UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{
self.slider.transform = CGAffineTransformMakeTranslation(0, 0.0);
}];
} completion:^(BOOL finished) {
}];
However, it comes out looking like this with this delay after the animation ends and before it restarts.
How do I make it fluid?
I'm not sure what effect you're going for exactly, but I think this gives you something like your code does without the delay. I usually do this by animating a constraint, rather than using transforms. In this example, I've made an IBOutlet (topCon) to the constraint to the top of the view:
-(IBAction)floatView:(id)sender {
static int i= 1;
static float duration = .25;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
self.topCon.constant = self.topCon.constant - (5 * i);
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
i = (i == 1 || i == 2)? -2 : 2;
duration = 0.5;
[self floatView:self];
}];
}

Reset animation state during user interaction

I have a circle that users can touch, when you touch it it changes size then reverts back to its original size to indicate you touched it. I want users to be able to touch it as often as they like regardless of whether its currently animating or not. I updated my animation to use the UIViewAnimationOptionAllowUserInteraction flag which does allow me to touch it during the animation but it doesnt behave as I'd expect.
I think I need to somehow stop the currently playing animation, reset the size to normal and then play it again, is this correct and if so how do I do it? If not what do I do?
- (void)pop{
[view.layer removeAllAnimations];
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction // reverse back to original value
animations:^{
// scale down 20%
self.transform = CGAffineTransformMakeScale(0.8, 0.8);
} completion:^(BOOL finished) {
self.transform = CGAffineTransformMakeScale(1, 1);
}];
}
self.btn = [[UIButton alloc] initWithFrame:CGRectMake(200, 200, 100, 30)];
[self.btn addTarget:self action:#selector(tapDown:) forControlEvents:UIControlEventTouchDown];
[self.btn addTarget:self action:#selector(tapUp:) forControlEvents:UIControlEventTouchUpInside];
- (IBAction)tapDown:(id)sender
{
[UIView animateWithDuration:0.2
delay:0.0
options: UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
// scale down 20%
self.btn.transform = CGAffineTransformMakeScale(0.8, 0.8);
} completion:nil];
}
- (IBAction)tapUp:(id)sender {
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction // reverse back to original value
animations:^{
// scale up to 100%
self.btn.transform = CGAffineTransformMakeScale(1, 1);
} completion:nil];
}
Sure this is not what you want? When the player taps and pop is called the animation should start over?
- (void)pop{
self.transform = CGAffineTransformMakeScale(1, 1); // If you want the animation to start over you need to reset the size before staring it again
[view.layer removeAllAnimations];
[UIView animateWithDuration:0.2
delay:0.0
options: options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionCurveEaseOut| UIViewAnimationOptionAllowUserInteraction // reverse back to original value
animations:^{
// scale down 20%
self.transform = CGAffineTransformMakeScale(0.8, 0.8);
} completion:^(BOOL finished) {
self.transform = CGAffineTransformMakeScale(1, 1);
}];
}

UIImageView Zoom/Fade animation?

I want to make a little zoom/fade animation for when the UIImageView shows up in my view, I already have the code for the fade effect:
banner.alpha = 0.0;
[UIView animateWithDuration:2.0 animations:^{
banner.alpha = 1.0;
}];
Now I want to know if there is another easy way to combine the fade effect with a little zoom effect, like the image becoming larger and filling up the frame as it fades in? Any ideas?
Thanks!
you can use CG_EXTERN CGAffineTransform CGAffineTransformMakeScale(CGFloat sx, CGFloat sy) to do the zoom effect
such as
banner.alpha = 0.0;
[UIView animateWithDuration:2.0 animations:^{
banner.alpha = 1.0;
banner.transform =CGAffineTransformMakeScale(1.3,1.3);
}];
You can also use the frame
banner.alpha = 0;
[UIView animateWithDuration:2.0f animations:^(void){
banner.alpha = 1.0f;
[banner setFrame:CGRectMake(0, 0, 1024, 748)];
}];
// With Completion
[UIView animateWithDuration:0.1f animations:^(void){
banner.alpha = 1.0f;
[banner setFrame:CGRectMake(0, 0, 1024, 748)];
}completion:^(BOOL finished) {
}];

Resources