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

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];
}
}
}

Related

How to make two view animations run one by one?

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.

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];
}

How to hide tabbar and navigationbar when tapped on the view

I was building an articles based application,i am having tab bar and navigation bar in my application.What i want to do is while my article is displaying when i tap on that view,the tabbar and navigationbar should hide and viceversa.
Please help me in this
Thanks for the responses,Finally i have used gesture method
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleDoubleTap)];
doubleTap.numberOfTapsRequired =1;
[scrollView addGestureRecognizer:doubleTap];
[doubleTap release]; - (void)handleDoubleTap {
NSLog(#"Single tap");
if(firstTime)
{
[UIView beginAnimations: #"moveField"context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 0];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[self.navigationController setNavigationBarHidden:YES animated:YES];
scrollView.frame = CGRectMake(0,0,320,460.0f);
tabBar.hidden=YES;
[self.view bringSubviewToFront:scrollView];
[UIView commitAnimations];
firstTime=NO;
}
else {
[UIView beginAnimations: #"moveField"context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 0];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
//[self.view bringSubviewToFront:scrollView];
[self.navigationController setNavigationBarHidden:NO animated:YES];
scrollView.frame = CGRectMake(0.0, 0.0, 320, 372);
tabBar.hidden=NO;
[UIView commitAnimations];
firstTime=YES;
}
Now iam getting this when i tap on the screen...Is it possible to hide the tabbar and navigationbar wheni scroll the view and vice versa....Please help me in this
Use one BOOL variable i called it firstTime in .h file
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if(firstTime)
{
[self.navigationController hidesBottomBarWhenPushed];
firstTime=FALSE;
self.navigationController.navigationBar.hidden=TRUE;
}
else
{
[self.navigationController hidesBottomBarWhenPushed];
firstTime=TRUE;
self.navigationController.navigationBar.hidden=FALSE;
}
}
- (BOOL)hidesBottomBarWhenPushed
{
if(firstTime)
{
return TRUE;
}
else
{
return FALSE;
}
}
this will hide your Tabbar and NavigationBar on single tap and viceversa
int DEF_BAR_HEIGHT = 40;
-(void)hideBars:(bool)value
{
// hide navigation bar
[self.navigationController setNavigationBarHidden:value animated:YES];
//hide tabBar
CGRect viewFrame = view.frame;
viewFrame.size.height += value ? DEF_BAR_HEIGHT : -DEF_BAR_HEIGHT; // Change this to the height of the tab bar
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
view.frame = viewFrame;
[UIView commitAnimations];
}
I'm not sure about DEF_BAR_HEIGHT value. Try 40 or 40 plus navigationBar height.

For iphone development, how to flip a UIImageView?

I want to flip an imageView (left/right), but I can not find a UIView (or UIImageView) method to do that? any idea?
thanks!
I think the only thing you're looking for is:
UIView's
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache;
and
UIViewAnimationTransitionFlipFromLeft,
UIViewAnimationTransitionFlipFromRight,
These animation transitions can only be used within an animation block. The transition is set on the container view and then the old view is swapped out for the new view, then the animation is committed.
Like:
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:yourContainerView cache:YES];
[yourContainerView exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
[UIView commitAnimations];
Put your UIIMageView into a UIView and use this code (from the utility app project sample)
- (void)loadFlipsideViewController {
FlipsideViewController *viewController = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
self.flipsideViewController = viewController;
[viewController release];
// Set up the navigation bar
UINavigationBar *aNavigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)];
aNavigationBar.barStyle = UIBarStyleBlackOpaque;
self.flipsideNavigationBar = aNavigationBar;
[aNavigationBar release];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(toggleView)];
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:#"Test123"];
navigationItem.rightBarButtonItem = buttonItem;
[flipsideNavigationBar pushNavigationItem:navigationItem animated:NO];
[navigationItem release];
[buttonItem release];
}
- (IBAction)toggleView {
/*
This method is called when the info or Done button is pressed.
It flips the displayed view from the main view to the flipside view and vice-versa.
*/
if (flipsideViewController == nil) {
[self loadFlipsideViewController];
}
UIView *mainView = mainViewController.view;
UIView *flipsideView = flipsideViewController.view;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:([mainView superview] ? UIViewAnimationTransitionFlipFromRight : UIViewAnimationTransitionFlipFromLeft) forView:self.view cache:YES];
if ([mainView superview] != nil) {
[flipsideViewController viewWillAppear:YES];
[mainViewController viewWillDisappear:YES];
[mainView removeFromSuperview];
[infoButton removeFromSuperview];
[self.view addSubview:flipsideView];
[self.view insertSubview:flipsideNavigationBar aboveSubview:flipsideView];
[mainViewController viewDidDisappear:YES];
[flipsideViewController viewDidAppear:YES];
} else {
[mainViewController viewWillAppear:YES];
[flipsideViewController viewWillDisappear:YES];
[flipsideView removeFromSuperview];
[flipsideNavigationBar removeFromSuperview];
[self.view addSubview:mainView];
[self.view insertSubview:infoButton aboveSubview:mainViewController.view];
[flipsideViewController viewDidDisappear:YES];
[mainViewController viewDidAppear:YES];
}
[UIView commitAnimations];
}
mainView and flipToView are objects of imageViews and containerView is an object of UIView.
Given below are two sample code to curl the imageView and to flip the ImageView from left to Right
- (void)curlAction:(id)sender
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:([mainView superview] ? UIViewAnimationTransitionCurlUp : UIViewAnimationTransitionCurlDown)forView:containerView cache:YES];
if ([flipToView superview])
{
[flipToView removeFromSuperview];
[containerView addSubview:mainView];
}
else
{
[mainView removeFromSuperview];
[containerView addSubview:flipToView];
}
[UIView commitAnimations];
}
and to bring the image from left to right here's the code
- (void)flipAction:(id)sender
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:([mainView superview] ?
UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight)
forView:containerView cache:YES];
if ([flipToView superview])
{
[flipToView removeFromSuperview];
[containerView addSubview:mainView];
}
else
{
[mainView removeFromSuperview];
[containerView addSubview:flipToView];
}
[UIView commitAnimations];
}
Thank &Regards
Another solution is available at my repo but it does'nt involve animation yet! It only manipulates image orientations to provide for some image effects namely flip vertically/horizontally and rotate 90 degrees left/right.

presentModalViewController gives error?

if i run following gives error,current controller is table controller....
SetController *aSecondView = [[SetController alloc] initWithNibName:#"Sets" bundle:nil];
SchedAppDelegate *mainDelegate = (SchedAppDelegate *)[[UIApplication sharedApplication] delegate];
[mainDelegate setSettingsViewController:aSecondView];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:[[self view] superview] cache:YES];
[self.view removeFromSuperview];
[self presentModalViewController:aSecondView animated:NO];
//[aSecondView release];
[UIView commitAnimations];
It appears that mView is a UIViewController and not a UIView.
This is the proper way to apply a custom animation to a modal view controller:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self view] cache:YES];
[self presentModalViewController:mView animated:NO];
[UIView commitAnimations];
If mView is a view controller, you can present it with a flip animation by doing the following:
mView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:mView animated:YES];
The modalTransitionStyle property is only available for iPhone OS 3.0 onwards. Hope this helps. :)