In my code I programmatically change leftBarButtonItem with a UIButton to a UIActivityIndicatorView, I would like to know how to perform a flip transition when changing, any idea ?
Thanks a lot.
Hmm.. I have a feeling that to do a flip transition, you need to have a UIView.
So.. you could make a custom barButtonItem and add to it a flipView:
UIView *flipView = [[UIView alloc] init....];
BarButtonItem *barbutton = [[BarButtonItem alloc] initWithCustomView:flipView];
then add your original view to the flipView, this can contain whatever you like...
[flipView addSubview:<original view>];
Then to flip this into a UIActivityIndicatorView, I think you need to do something like this:
[UIView beginAnimations:#"flip" context:NULL];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:flipView cache:YES];
[<original view> removeFromSuperView];
[flipView addSubview:<activityIndicatorView>];
[UIView commitAnimations];
You'll probably have to keep a reference to your flipView somewhere so you can bring back a reference to it when you want to perform the flip.
Hope this helps!
Nick.
Take a look at the Elements sample. They are doing a flip in a toolbar there.
Related
I've just started objective C and I'm enhancing a current iPhone app. Previous codes were done by someone else. I'm trying to switch views back - and add a page curl animation in, but when I try to go back (removefromsuperview) my screen just goes white. I understand that I'm referring to the wrong view but I have no idea how to refer it to the right one.
-(IBAction)switchBack{
[UIView beginAnimations:#"flipview" context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView: self.view.superview cache:YES];
//[self.navigationController popToRootViewControllerAnimated:YES];
[self.view removeFromSuperview];
[UIView commitAnimations];
}
The commented out popToRootViewController allows me to go back to the previous page. Any help would be really appreciated. I'm going crazy with all this views >< Thanks!
Try something like this:
[UIView transitionWithView:self.navigationController.view duration:1.0 options:UIViewAnimationOptionTransitionCurlDown
animations:^{
[self.navigationController popToRootViewControllerAnimated:NO];
}
completion:NULL];
that happened because you're trying to remove the view from its superview, which is not the way it is added before, don't use removeFromSuperView if you didn't use addSubview when showing the view it self.
you should add this code to the parent which calls your current view
viewNotLoggedHome.modalTransitionStyle =
UIModalTransitionStylePartialCurl;
this way you've stated a "partial curl" transition animation for the view u're pushing
and just delete all your animation block on switchBack function so it only consist of
-(IBAction)switchBack
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
Instead of usign self.view which is a reference to your superview, you need to use the name of the view you want to use.
f.e. :
- If you have view1 and view2
- you can delete view1 by using
[view1 removeFromSuperview];
I did some digging around about this, but nothing really seems to answer my particular question (not even this: Is it possbile to removeFromSuperview with Animation?).
Basically, my app starts with a welcome screen, where a user clicks on "sign in", then goes to the sign in view, then getting to a tab bar view, which is the actual app.
The way I did it, is that I wrote a custom class - TabBarController, which sets up all the tabs and their respective view controllers. Now, when the user clicks on "sign in" i am calling removeFromSuperview and present the tabbar.
I am trying to find a way to animate the transition from the sign in page to the tab bar. I tried some proposed solutions around here, but none seems to do the job. Here is my code in the signin.m view controller. I am looking to animate out the current view (ideally, not just by fading out, but more cool stuff like flips, etc.).
//when done signing in --> go to the tab bar view
-(IBAction)done:(id)sender {
TabBarController *tabController = [[TabBarController alloc] init];
[UIView beginAnimations:#"removeWithEffect" context:nil];
[UIView setAnimationDuration:4.0];
self.parentViewController.view.frame = CGRectMake(0,0,320,480);
self.parentViewController.view.alpha = 1.0f;
[UIView commitAnimations];
[self.parentViewController.view performSelector:#selector(removeFromSuperview) withObject:nil afterDelay:2.5f];
[self presentModalViewController:tabController animated:YES];
}
Appreciate any help!
That can't work that way. presentModalViewController dislpays the view of a viewController over the own view. It won't replace the source viewController (self).
Since you remove self.parentViewController.view from the view hierarchy, it can't present your tabController modally because you have removed self.
Anyway, i would recommend you another way to achieve your view layout:
Create a tabBarViewController and add its view to a rootView (self.window in the app delegate or whatever you are using now). Then add your login-view to the same view. Due the view hierarchy, the login-view will be displayed above the tabBar.view. And the done button should be implemented this way: (i'm using block syntax for animation as it should be)
-(IBAction)done:(id)sender {
[UIView animateWithDuration:1.0
animations:^{
self.view.frame = CGRectMake(0, 480, 320, 480);
self.view.alpha = 0.0
}
completion:^(BOOL finished){
[self.view removeFromSuperView];
}
];
}
You can animate more things than just the alpha, size or position. Just take a look about animations in the documentation. I guess, you'll be interested in view.transform to commit flip animations. ;)
This is how you have to remove the view after animating it.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelay:2.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:myView];
[UIView setAnimationDidStopSelector:#selector(removeFromSuperview)];
[UIView commitAnimations];
Hope this helps.
Happy coding.
I have a method like the following:
- (void)add:(id)sender {
MyAddViewController *controller = nil;
controller = [[MyAddViewController alloc] initWithAddType:1];
//controller.delegate = self;
// Do some animation. Slide it in from the right side of the screen.
CGPoint initialCenter = self.view.center;
controller.view.center =
CGPointMake(initialCenter.x + 320, initialCenter.y);
// Add the subview now with it's center + 320 off the screen.
[self.view addSubview:controller.view];
[UIView beginAnimations:#"animation" context:NULL];
[UIView setAnimationDuration:0.35];
[UIView setAnimationDelegate:self];
controller.view.center = CGPointMake(initialCenter.x, initialCenter.y);
//[UIView setAnimationDidStopSelector:#selector(aMethodToBeCalledAfterAnimationEnd:finished:context:)];
[UIView commitAnimations];
//[controller release];
}
You see I have a controller release as the last line in my add method. If I uncomment this line the animation completely dies and it just dumps the view into place with no animation.
Is there a better way to do release without having to create another method which does cleanup via [UIView setAnimationDidStopSelect:#selector(aMethodToBeCalledAfterAnmiationEnd... ?
Or can I do something like setAnimationDidStopSelector:#selector([controller release]) ? :)
Thanks in advance!
Using setAnimationDidStopSelector: is the proper way to solve the generic problem of releasing resources after an animation completes.
Take a step back and reconsider what you're doing here, though. Why are you looking to free the controller you just created? If you are only creating the controller for the purpose of getting at the view, that isn't the right way to do it. Build yourself a factory method to create your view, or use the methods in NSBundle to load the view from a NIB.
You can do this:
[UIView setAnimationDelegate: controller];
[UIView setAnimationDidStopSelector:#selector(release)];
I see you tagged this iphone-sdk-4.0. You could use the new block-based animations to do this and any other cleanup. See the documentation for details.
this feels like a beginner question, but since I am not able to get it working in the intended-fashion, I am hoping somewhere out there is able to point me in the right direction.
What I am trying to achive is a transition of a view inside a view.
I fundamentally want to replace a view inside a view with another view(controller?!?) 's content.
lets say, I have an image of a book and I want to do a transition inside the book to another page (going from the calendar-view to the detailed daily view for example). I only want the "book-content"(white content area) to be included in that transition, and not the whole book itself(whole screen).
I can do a transition with the same view, no problem, but I dont get it working trying to replace the view with a completly different view.
It didnt matter having the views in seperate viewcontrollers, or all the views in one viewcontroller, so I were not able to get it working yet, but even worse, I am running out of ideas.
So HELP! If please somebody out there could be so kind and tell me what I am doing wrong.
Suggestions also very much appreciated.
Thanks!!
Tom
Maybe you could hide one view then show the other using a UIView Animations block.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view1.view cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view2.view cache:YES];
[UIView setAnimationDuration: 1.5];
[UIView commitAnimations];
view1.view.hidden = YES;
view2.view.hidden = NO;
Edit: Is this what you were looking for?
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[view1 viewWillDisappear:YES];
[view2 viewWillAppear:YES];
view1.view.hidden = YES;
view2.view.hidden = NO;
[view1 viewDidDisappear:YES];
[view2 viewDidAppear:YES];
[UIView commitAnimations];
Or, you could use something like this:
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[view1 removeFromSuperview];
[mySuperview addSubview:view2];
}
completion:nil];
Check out the exchangeSubviewsAtIndex: method in the UIView class. Just set up the 2 views that you want to transition from and to as subviews of another view; then call this method on that parent view.
Suppose you have a view controller with two views, A and B. They have identical frames so they occupy the same space in the controller's view, for your purposes displaying a page of a book. You want to display one and transition to the other.
One way would be to set the alpha property of one to 1.0 (opaque) and the other to 0.0 (transparent). Because this property can be animated you could do a fade from one to the other using a beginAnimations:context/commitAnimations, or use one of the block methods like the docs advise.
Another way would be to animate a change in frame in the two views. Set up the views so that one has a frame such that it is in the right place to display, the other has the same frame but with frame.origin.x equal to frame.size.width - it will be hidden because it is off-screen or hidden behind some other view. Animate the frame in by setting view A's frame.origin.x to -frame.size.width and frame B's frame.origin.x to the display position x origin. Then set (no animation) frame A's frame.origin.x to frame.origin.width again, update its content and you are ready to slide another page in from the right.
I have the following code to do a UIView animation:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:mapView.view cache:NO];
[self addSubview:detailView];
[mapView removeFromSuperview];
[UIView commitAnimations];
It works when I dont add the detailView.
What actually happens is the equivalent of this:
[self addSubview:detailView];
[mapView removeFromSuperview];
i think you have the order wrong. you need to remove the old subview first before adding the new one.
see reference for setAnimationTransition:forView:cache:
you can also use CATransition on the layer of a view. and then use layer animations.
if you specifically want to flip the new view you can also use presentalModalViewController method of uiviewcontroller.
I have seen your code in tutorials all the time and never works for me. I always use this:
UIViewController *mainViewController = [[YourMainViewController alloc] init];
UIViewController *viewControllerToSwitchTo = [[ViewControllerToSwitchTo alloc] init];
[mainViewController presentModalViewController:viewControllerToSwitchTo animated: YES];
you can set the view changing style with:
[setModalTransitionStyle:WhateverModalTransitionStyleYouWant];
but make sure this goes before the transition method.
That code won't work. From Apple's documentation:
If you want to change the appearance
of a view during a transition—for
example, flip from one view to
another—then use a container view, an
instance of UIView, as follows:
Begin an animation block.
Set the transition on the container view.
Remove the subview from the container view.
Add the new subview to the container view.
Commit the animation block.
So the transition should be applied to self not your mapView, and your add/remove are in reverse order.
I had to set the graphics context to UIGraphicsGetCurrentContext()