I've been trying to minimize all my functions in my app but can't really find how to make this function better, maybe someone is a lot better at this than me? :)
-(void)showRivBoxWithAnimtation:(BOOL)yesno {
if(yesno) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
if ([self alpha] > 0) {
[self setAlpha:0.0];
[appDelegate.JSONparser setDelegate:self.delegate]; //Give back the JSONparser to the parent!
} else {
[self setAlpha:1.0];
}
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(clearRivBoxContent:finished:context:)];
[UIView commitAnimations];
} else {
if ([self alpha] > 0) {
[self setAlpha:0.0];
[appDelegate.JSONparser setDelegate:self.delegate]; //Give back the JSONparser to the parent!
} else {
[self setAlpha:1.0];
}
}
}
This is what I would do:
-(void)showRivBoxWithAnimtation:(BOOL)yesno {
[UIView animateWithDuration:yesno ? 0.2 : 0.0
animations:^{
if ([self alpha] > 0) {
[self setAlpha:0.0];
[appDelegate.JSONparser setDelegate:self.delegate]; //Give back the JSONparser to the parent!
} else {
[self setAlpha:1.0];
}
}
completion:^(BOOL finished){
if (finished) {
// Do the stuff from clearRivBoxContent:finished:context:
}
}];
}
Unless the order of operations wrt. alpha is critical; this is probably the smallest it can be made.
-(void)showRivBoxWithAnimtation:(BOOL)yesno {
if ([self alpha] > 0) {
[self setAlpha:0.0];
[appDelegate.JSONparser setDelegate:self.delegate]; //Give back the JSONparser to the parent!
} else {
[self setAlpha:1.0];
}
if(yesno) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(clearRivBoxContent:finished:context:)];
[UIView commitAnimations];
}
}
Related
I am trying to make my label appear with animation:
- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {
if (isShowingRectangleLabel == NO) {
[UIView transitionWithView:rectangleLabel duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^ { [self.view addSubview:rectangleLabel]; }
completion:nil];
NSLog(#"action");
isShowingRectangleLabel = YES;
} else {
[UIView transitionWithView:rectangleLabel duration:0.5
options:UIViewAnimationOptionTransitionFlipFromBottom
animations:^ { [rectangleLabel removeFromSuperview]; }
completion:nil];
isShowingRectangleLabel = NO;
}
}
But this animation works only after second adding to subview. How can I fix it?
EDIT To clarify, addSubview works but without animation.
Do this:
- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {
if (isShowingRectangleLabel == NO) {
[UIView transitionWithView:self.view duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^ { [self.view addSubview:rectangleLabel]; }
completion:nil];
NSLog(#"action");
isShowingRectangleLabel = YES;
} else {
[UIView transitionWithView:self.view duration:0.5
options:UIViewAnimationOptionTransitionFlipFromBottom
animations:^ { [rectangleLabel removeFromSuperview]; }
completion:nil];
isShowingRectangleLabel = NO;
}
}
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.
I have some classes for watching pictures in gallery. in those classes after enabling ARC i get message that implicit conversion is forbidden by ARC and I cant run the application.
Those methods are:
- (void) curlToPrevious
{
if (currentImageIndex == 0) return;
if ([self.image2 superview] == NO) {
self.image2.image = (UIImage*) [imageViews objectAtIndex:(currentImageIndex-1)];
} else {
self.image1.image = (UIImage*) [imageViews objectAtIndex:(currentImageIndex-1)];
}
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kTransitionDuration];
currentImageIndex--;
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.containerView cache:YES];
if ([self.image2 superview] == NO) {
[self.image1 removeFromSuperview];
[self.containerView addSubview:self.image2];
} else {
[self.image2 removeFromSuperview];
[self.containerView addSubview:self.image1];
}
[UIView commitAnimations];
[self updateCurrentImageCounter];
}
- (void) curlToNext
{
if (currentImageIndex == ([self imageCount]-1)) return;
if ([self.image2 superview] == NO) {
self.image2.image = (UIImage*) [imageViews objectAtIndex:(currentImageIndex+1)];
} else {
self.image1.image = (UIImage*) [imageViews objectAtIndex:(currentImageIndex+1)];
}
currentImageIndex++;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kTransitionDuration];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.containerView cache:YES];
if ([self.image2 superview] == NO) {
[self.image1 removeFromSuperview];
[self.containerView addSubview:self.image2];
} else {
[self.image2 removeFromSuperview];
[self.containerView addSubview:self.image1];
}
[UIView commitAnimations];
[self updateCurrentImageCounter];
}
I have
if ([self.image2 superview] == NO) {
In this line on 4 places in code problem.
The text I get is:
implicit conversion of 'int' to 'UIView' is disallowed with ARC
How can I avoid this??? Thanks.
you can replace your code on this if ([self.image2 superview] == nil)
You are comparing an UIView* with an integer (0) - of course you get a warning. Do you want to check whether the superview is nil? Then just do that:
if([self.image2 superview] == nil) { ... }
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.
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];
}
}
}