How to make two view animations run one by one? - iphone

I am to make "Guess match card" game, that is :there are 24 cards(UIImageView) in the windows with hide inside view shown surface, They a 12 groups number,you touch one, then it will be open show inside,find if there has a same card opened, if not matched, two opened card will then hide.
Just this.
open card and hide card action used UIView animation. But now I have a problem.when I touched card, it then try to find if there has a match. But open card and close card action animation execute at same time. even I can't see what card content I see clear.
I want to open a card after I touch it, then (even wait for 0.5 second) close the opend not matched cards at same time. not open card and close card at same time. But in my code below I did open a card first,then compute, and close two opend card then.
#interface Card : UIImageView
#property BOOL expanded;
#property BOOL found;
#property (retain)NSString * nameTitle;
#property (retain) UIImage * expandedImage;
#end
//
// Card.m
// Guest card match
//
// Created by on 11-10-20.
// Copyright 2011年 __MyCompanyName__. All rights reserved.
//
#import "Card.h"
#import "MainAppDelegate.h"
#implementation Card
#synthesize expanded;
#synthesize found;
#synthesize expandedImage;
#synthesize nameTitle;
- (id)init
{
if ((self = [super init])) {
[self setUserInteractionEnabled:YES];
self.image = [UIImage imageNamed:#"cardface_48.png"];
self.expanded = NO;
self.found = NO;
}
return self;
}
- (void)openCard{
NSLog(#"open card");
if (self.expanded){return;}
self.expanded = YES;
[UIView beginAnimations:#"animation1" context:nil];
[UIView setAnimationDuration:0.8];
[UIView setAnimationDelegate:self];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
[self setTransform:CGAffineTransformMakeScale(3.0, 3.0)];
[self setImage:self.expandedImage];
[UIView commitAnimations];
[UIView beginAnimations:#"animation1_open" context:nil];
[UIView setAnimationDuration:1.2];
[UIView setAnimationDelegate:self];
[UIView setAnimationBeginsFromCurrentState:NO];
[self setTransform:CGAffineTransformMakeScale(1, 1)];
[UIView commitAnimations];
}
- (void)closeCard{
if (!self.expanded){return;}
self.expanded = NO;
[UIView beginAnimations:#"animation1_close" context:nil];
[UIView setAnimationDuration:0.8];
[UIView setAnimationDelegate:self];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
[self setTransform:CGAffineTransformMakeScale(3.0, 3.0)];
[self setImage:[UIImage imageNamed:#"cardface_48.png"]];
[UIView commitAnimations];
[UIView beginAnimations:#"animation2_close" context:nil];
[UIView setAnimationDuration:1.2];
[UIView setAnimationDelegate:self];
[UIView setAnimationBeginsFromCurrentState:NO];
[self setTransform:CGAffineTransformMakeScale(1, 1)];
[UIView commitAnimations];
[self setUserInteractionEnabled:YES];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// Do what you want here
//NSLog(#"touchesBegan!");
//[self setUserInteractionEnabled:NO];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"card tag: %d", self.tag);
if (self.expanded) {
return;
}
[self openCard];
for (NSInteger tagNumber=10001; tagNumber<10025; tagNumber++) {
Card *card = (Card *)[self.superview viewWithTag:tagNumber];
if (card.expanded && card.tag != self.tag && !card.found) {
if ([card.nameTitle isEqualToString:self.nameTitle]) {// Found match!
NSLog(#"Match!");
[card setUserInteractionEnabled:NO];
[self setUserInteractionEnabled:NO];
card.found = YES;
self.found = YES;
}else{
NSLog(#"not Match!");
[card closeCard];
[self closeCard];
}
}else{
[self setUserInteractionEnabled:YES];
}
}
}
#end
Update: I followed Kashiv, and this updated code:
- (void)openCard{
NSLog(#"open card");
if(cardAnimationIsActive) return;
cardAnimationIsActive = YES;
if (self.expanded){return;}
self.expanded = YES;
[UIView animateWithDuration:2.0f animations:^{
[UIView beginAnimations:#"animation1" context:nil];
[UIView setAnimationDuration:0.8];
[UIView setAnimationDelegate:self];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
[self setTransform:CGAffineTransformMakeScale(3.0, 3.0)];
[self setImage:self.expandedImage];
[UIView commitAnimations];
[UIView beginAnimations:#"animation1_open" context:nil];
[UIView setAnimationDuration:1.2];
[UIView setAnimationDelegate:self];
[UIView setAnimationBeginsFromCurrentState:NO];
[self setTransform:CGAffineTransformMakeScale(1, 1)];
[UIView commitAnimations];
} completion:^(BOOL finished){
cardAnimationIsActive = NO;
}];
}
- (void)closeCard{
if(cardAnimationIsActive) return;
cardAnimationIsActive = YES;
if (!self.expanded){return;}
self.expanded = NO;
[UIView animateWithDuration:5.0f animations:^{
[UIView beginAnimations:#"animation1_close" context:nil];
[UIView setAnimationDuration:0.8];
[UIView setAnimationDelegate:self];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
[self setTransform:CGAffineTransformMakeScale(3.0, 3.0)];
[self setImage:[UIImage imageNamed:#"android_48.png"]];
[UIView commitAnimations];
[UIView beginAnimations:#"animation2_close" context:nil];
[UIView setAnimationDuration:1.2];
[UIView setAnimationDelegate:self];
[UIView setAnimationBeginsFromCurrentState:NO];
[self setTransform:CGAffineTransformMakeScale(1, 1)];
[UIView commitAnimations];
[self setUserInteractionEnabled:YES];
} completion:^(BOOL finished){
cardAnimationIsActive = NO;
}];
}
But opencard and closecard animation still execute at same time.

You can acheive this by using block-based animation:
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
Then you can check if animation is still executing or is finished bu using BOOL iVar (e.g. cardAnimationIsActive).
Example:
- (void)openCard {
if(cardAnimationIsActive) return;
cardAnimationIsActive = YES;
[UIView animateWithDuration:duration animations:^{
--- your open animations ---
} completion:^(BOOL finished){
cardAnimationIsActive = NO;
}];
}
- (void)closeCard {
if(cardAnimationIsActive) return;
cardAnimationIsActive = YES;
[UIView animateWithDuration:duration animations:^{
--- your close animations ---
} completion:^(BOOL finished){
cardAnimationIsActive = NO;
}];
}

You could use:
[UIView setAnimationDelay:delay];
to delay all animations the proper time so they run in sequence.

[UIView animateWithDuration:0.2
animations:^{view.alpha = 0.0;}
completion:^(BOOL finished){ [view removeFromSuperview]; }];
You can create second animation in completion block.

Related

Blink hidden and using blocks

I have the method:
- (void)blinkView:(UIView *)view
{
view.layer.opacity = 0.0f;
view.hidden = NO;
[UIView beginAnimations:#"Blinking" context:nil];
[UIView setAnimationRepeatCount:1.0];
[UIView setAnimationDuration:0.6f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
view.layer.opacity = 1.0f;
[UIView commitAnimations];
}
How can i write this code with blocks, and how i must implement method with reverse effect (hide uiview with blink) ?
[UIView transitionWithView: view
duration:0.6f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{ view.layer.opacity = 1.0f; }
completion:NULL];
or
[UIView transitionWithView: view
duration:0.6f
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^{ view.layer.opacity = 1.0f; }
completion:NULL];
You can set the repeat count by recursively calling the animation block (see here).
Hope it will help you.
You can use UIView's setAnimationDelegate: and setAnimationDidStopSelector:
[UIView beginAnimations:#"Blinking" context:nil];
[UIView setAnimationRepeatCount:1.0];
[UIView setAnimationDuration:0.6f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
view.layer.opacity = 1.0f;
[UIView commitAnimations];
- (void) animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
// add your final code here : you can give new animation effect here.
}
Or try animateWithDuration (available only in iOS 4 or later)
[UIView animateWithDuration:0.6f
animations:^{
view.layer.opacity = 1.0f;
}
completion:^(BOOL completed){
// add your final code here : you can give new animation effect here.
}
];

UIView animation for CGAffineTransformMake not working

I have a simple transform animation that moves a UITableViewCell 70 pixels to the left. In the if part, the animation works just fine and I get a smooth transition. However, when the function is called again to put the cell back in its original position, which is the else part, I get no animation. It just returns back to normal but without animation. How can I fix this?
if([[slideArray objectAtIndex:indexPath.row] intValue]==0)
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
selectedCell.transform=CGAffineTransformMakeTranslation(-70, 0);
[UIView commitAnimations];
[slideArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithInt:1]];
}
else
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
selectedCell.transform=CGAffineTransformMakeTranslation(0, 0);
[UIView commitAnimations];
[slideArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithInt:0]];
}
try the following animation in else condition this will work fine if you alreadyb have perform translation of if condition....
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
selectedCell.transform=CGAffineTransformMakeTranslation(70, 0);
[UIView commitAnimations];
[slideArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithInt:0]];
if above code not working for you than try the following
[UIView animateWithDuration:0.5
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:(void (^)(void)) ^{
myImageView.transform=CGAffineTransformMakeTranslation(-70, 0);
}
completion:^(BOOL finished){
myImageView.transform=CGAffineTransformIdentity;
}];
[slideArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithInt:0]];
let me know if any issues ..
regards.

Subview fade in and fade out help

I am having a problem fading out my subview. I have no trouble fading the view in but fading out ..just drops the view.
-(void)flipToReview {
ReviewViewController *reviewVariable = [[ReviewViewController alloc] initWithNibName:#"ReviewViewController" bundle:nil];
[self setReviewViewController:reviewVariable];
self.ReviewViewController.view.alpha =0;
[UIView beginAnimations:#"flipview" context:nil];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:_window cache:YES];
[reviewVariable release];
[self.window addSubview:self.ReviewViewController.view];
self.ReviewViewController.view.alpha =1;
[UIView commitAnimations];
}
-(void)flipBackFromReview {
// self.ReviewViewController.view.alpha = 1;
[UIView beginAnimations:#"trip" context:nil];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:_window cache:NO];
self.ReviewViewController.view.alpha = 0;
[self.ReviewViewController.view removeFromSuperview];
[UIView commitAnimations];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
[self.ReviewViewController.view setHidden:1];
NSLog(#"remove subview");
}
Try the following:
[UIView animateWithDuration:3.0 delay:0.0
options:UIViewAnimationOptionAllowUserInteraction
animations:^{ ReviewViewController.view.alpha = 0.0;}
completion:^(BOOL fin) {
if (fin) [ReviewViewController.view removeFromSuperview];
}];
You need to move:
[self.ReviewViewController.view removeFromSuperview];
That cannot be done "over time" in an animation. What you want to do is move that to a selector and use setAnimationDelegate and setAnimationDidStopSelector. Put the following in your animation block:
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(finshedFadeOut)];
Then make the following method:
- (void)finshedFadeOut {
[self.ReviewViewController.view removeFromSuperview];
}
I had this issue as well, the way I got around it was changing the alpha to 0, instead of just removing the view. That can be animated.

How to animate a UITextView that is a subview?

I am trying to animate a UITextView (myTextView) that is a subview inside a UIScrollView (scrollView).
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:myTextView cache:YES];
[scrollView addSubview:myTextView];
[UIView commitAnimations];
myTextView appears without animation!
What kind of animation do you want to do? If you want to fade in, for example, you have to do
[scrollView addSubview:myTextView];
myTextView.alpha = 0.0;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:myTextView cache:YES];
myTextView.alpha = 1.0;
[UIView commitAnimations];
You can change several properties (e.g.: frame, transform) to make animations.
http://www.4shared.com/dir/-PGqZEXR/zoominzoomout.html just add this file with your project and call it through this functions
here im2 is UIVIEW and i paste image on it then passing this through view didload like this
- (void)viewDidLoad {
[self loadFlowersInView:im2];
[self.view addSubview:im2];
}
now attach this function like this
- (void) loadFlowersInView: (UIView *) backdrop {
NSString *create_button = nil; // Add the flowers to random points on the screen
for (int i = 0; i < 1; i++) {
MagPicAppDelegate *appdelegate = (MagPicAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *whichFlower = appdelegate.imageName;
UIImage *stemp = [UIImage imageNamed:#"approve.png"];
DragView *dragger = [[DragView alloc] initWithImage:stemp];
dragger.userInteractionEnabled = YES;
dragger.center = CGPointMake(160.0f, 140.0f);
[im2 addSubview:dragger];
[dragger release];
}
[self.view addSubview:im2];
[im2 release];
}

iphone : Switching views like a picture book, problem with removeFromSuperView

Right I know how to do the pictue book effect but I struggling to remove the view
So page 1, I add the second page view via addSubview (via a swipe). I also increment a counter so I know what page I am on.
So how do I return to page 1? See I thought it would be self.view removeFromSuperview but that crashes when you try to go back to page 2
Code below
- (void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
//NSLog(#"swipe right to left");
UniversalAppAppDelegate *appDelegate = (UniversalAppAppDelegate *)[[UIApplication sharedApplication] delegate];
PictureBookViewController *viewController2 =(PictureBookViewController *) [appDelegate getViewControllerForViewID:#"81"];
[UIView beginAnimations:Nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view.superview cache:YES];
self.viewController = viewController2;
self.viewController.pageNo = self.pageNo + 1;
[self.view addSubview:self.viewController.view];
[UIView commitAnimations];
[viewController2 release];
} else {
//NSLog(#"swipe left to right");
NSLog([NSString stringWithFormat:#"%d", self.pageNo]);
if (self.pageNo > 0) {
[UIView beginAnimations:Nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view.superview cache:YES];
//self.viewController = viewController2;
//self.viewController.pageNo = self.pageNo - 1;
//[self.view addSubview:self.viewController.view];
[self.view removeFromSuperview];
//[self.view addSubview:self.viewController.view];
[UIView commitAnimations];
}
}
}
Update:
Each view has its own view controllers.
You want to remove your viewController's view, not the container's view.
[self.viewController.view removeFromSuperview];
This seems to work and not crash? I am now convinced it right. I just seem to need a way of removing the last added subview. My first view is not the superview
- (void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
//NSLog(#"swipe right to left");
UniversalAppAppDelegate *appDelegate = (UniversalAppAppDelegate *)[[UIApplication sharedApplication] delegate];
PictureBookViewController *viewController2 =(PictureBookViewController *) [appDelegate getViewControllerForViewID:#"82"];
[UIView beginAnimations:Nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view.superview cache:YES];
self.viewController = viewController2;
self.viewController.pageNo = self.pageNo + 1;
self.viewController.lastViewController = self;
[self.view addSubview:self.viewController.view];
[UIView commitAnimations];
[viewController2 release];
} else {
//NSLog(#"swipe left to right");
NSLog([NSString stringWithFormat:#"%d", self.pageNo]);
if (self.pageNo > 0) {
[UIView beginAnimations:Nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view.superview cache:YES];
self.pageNo --;
self.view = self.viewController.view;
[self.view removeFromSuperview ];
self.view = self.lastViewController.view;
[UIView commitAnimations];
}
}
}