I want to animate the transition of my LevelCompletedVC.
The LevelCompletedVC should come from Top to Bottom.
Here is my Code in the GameViewController:
LevelCompletedViewController *lcvc = [self.storyboard instantiateViewControllerWithIdentifier:#"levelCompletedViewController"];
[self.view addSubview:lcvc.view];
[lcvc.view setFrame:self.view.window.frame];
[lcvc.view setTransform:CGAffineTransformMakeTranslation(0, -self.view.frame.size.height)];
[lcvc.view setAlpha:1.0];
[UIView animateWithDuration:0.7 delay:0.0 options : UIViewAnimationOptionTransitionFlipFromTop
animations:^{
[lcvc.view setTransform : CGAffineTransformMakeTranslation(0, 0)];
[lcvc.view setAlpha:1.0];
}
completion:^(BOOL finished) {
[lcvc.view removeFromSuperview];
[self presentViewController:lcvc animated:NO completion:nil];
}];
If I want to present the second VC with:
LevelCompletedViewController *lcvc = [self.storyboard instantiateViewControllerWithIdentifier:#"levelCompletedViewController"];
[self presentViewController:lcvc animated:NO completion:nil];
theres no error.
But with my own transition i get:
Unbalanced calls to begin/end appearance transitions for LevelCompletedViewController.
Whats wrong?
I don't know when or where you present the second VC, but i got same
wrong before.
In my case, presentViewController are waiting other action done.
Try
dispatch_async(dispatch_get_main_queue(), ^(void){
LevelCompletedViewController *lcvc = [self.storyboard instantiateViewControllerWithIdentifier:#"levelCompletedViewController"];
[self presentViewController:lcvc animated:NO completion:nil];
});
hope this help you.
Related
How to animate the expansion of a UICollectionViewCell's content upon selection?
Currently I'm using transition animation on my didSelectItemAtIndexPath for animating a view Which isn’t working smoothly like AppStore card animation.
Here is my current code...
AnimateStaticImageViewController *animateImageVC = [[AnimateStaticImageViewController alloc] init];
animateImageVC.modalPresentationStyle = UIModalPresentationFullScreen;
animateImageVC.modelImage = [UIImage imageNamed:text];
[UIView animateWithDuration:0.7 animations:^{
animateImageVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.3);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.7 animations:^{
animateImageVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.7 animations:^{
animateImageVC.view.transform = CGAffineTransformIdentity;
}];
}];
}];
[self presentViewController:animateImageVC animated:NO completion:nil];
So, I was trying a modal transition animation in my app's home page staticImageCollectionView immediately after clicking the image.
The core animation & transform mechanism didn't work for me as I need something like AppStore's card animation.
Using this library worked after some hassle! Following this...
Setting the library with following steps.
Calling the transitioningDelegate of the animationViewController on didSelectItemAtIndexPath (or prepareForSegue if working with segue-navigation controller).
Calling it within a completion block to ignore flickering & delay issue in view presentation.
AnimatedStaticImageViewController *animateImageVC = [[AnimatedStaticImageViewController alloc] init];
animateImageVC.modalPresentationStyle = UIModalPresentationFullScreen;
animateImageVC.modelImage = [UIImage imageNamed:text];
[UIView animateWithDuration:0.2
animations:^{
animateImageVC.transitioningDelegate = self;
} completion:^(BOOL finished) {
[self.view removeFromSuperview];
[self presentViewController:animateImageVC animated:YES completion:nil];
}];
Be careful when setting imageView which is the main presentation of the animation.
Make sure you declaring the delegate 'RMPZoomTransitionAnimating' & 'RMPZoomTransitionDelegate' methods on both fromViewController and toViewController.
I am working with a custom transition, animation like that of a push.
But when i use this code after my viewcontroller loaded after after animation it just blinks.
Here is the method i used to present my view controller
+(void)leftpresentFrom:(UIViewController *)fromviewcontroller
To:(UIViewController *)toviewcontroller
{
CGPoint newcenter = CGPointMake(480, toviewcontroller.view.center.y);
toviewcontroller.view.center =newcenter;
toviewcontroller.view.clipsToBounds=YES;
[fromviewcontroller.view addSubview:toviewcontroller.view];
[UIView animateWithDuration:.5
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
toviewcontroller.view.center = CGPointMake(160 ,toviewcontroller.view.center.y);
}
completion:^(BOOL finished){
[toviewcontroller.view removeFromSuperview];
[fromviewcontroller presentViewController:toviewcontroller animated:NO completion:^{
}];
}];
}
did you try removing the view after the new controller has been presented?
eg.
[fromviewcontroller presentViewController:toviewcontroller animated:NO completion:^{
[toviewcontroller.view removeFromSuperview];
}];
I have a single view App and want to show a new ViewController when pressing a nav bar button in the right hand side. I call this VC by this code:
- (IBAction)createEntryButton:(id)sender {
CreateEntryViewController *vc2 = [[CreateEntryViewController alloc] init];
[self presentViewController:vc2 animated:TRUE completion:nil];
}
This animation, however, brings the vc2 in from the bottom which seems counter-intuitive according to my UI. So my question is:
How can I make my vc2 appear from the right instead of the bottom with presentViewController?
Thanks.
the cleanest would be to use a navigationController for pushing and popping views..
if you are already in a NavigationController
[self.navigationCtroller pushViewController:vc2 animated:TRUE completion:nil]
if you aren't, adapt the code where your view controller is added to the window. If your VC is the rootWindowController and you are not using storyboarding, this is likely in your AppDelegate
if you use storyboards, adapt the storyboard so you are inside a navigation controller
ELSE if you don't want that for any reason: :) just manually animate in the 2. VC's view using [UIView animate:vc2.view ....]
written inline -- method names don't match but shows general approach:
UIView *v = vc2.view;
CGRect f = v.frame;
f.origin.x += self.view.frame.size.width; //move to right
v.frame = f;
[UIView animateWithDuration:0.5 animations:^{
v.frame = self.view.frame;
} completion:^(BOOL finished) {
[self presentViewController:vc2 animated:NO completion:nil];
}];
in the completion block present the view controller vc2 non-animated as you already did that yourself
This helped me,
- (void)presentNewViewController{
NewViewController *objNewViewController =[[NewViewController alloc]initWithNibName:#"NewViewController" bundle:nil];
UIView *tempNewVCView = [UIView new];
tempNewVCView = objNewViewController.view;
tempNewVCView.frame = self.view.frame;
CGRect initialFrame = self.view.frame;
initialFrame.origin.x = self.view.frame.size.width;
tempNewVCView.frame = initialFrame;
[self.view addSubview:tempNewVCView];
[UIView animateWithDuration:0.3 animations:^{
tempNewVCView.frame = self.view.frame;
} completion:^(BOOL finished) {
[self presentViewController:objNewViewController animated:NO completion:^{
}];
}];
}
I am new to programming, I have been searching all night long and tyring to figure this out for a long time. Cant.... I dont want to use a navigation Controller but what I am trying to do is this.
So I have two classes in my project. Class1 and Class2. Now there is a button in Class1. If this button is pressed, I want the screen to go to Class2. The closest I got was creating a parent class but when I do that, the button remains on both classes.
- (IBAction)addScheduleB:(id)sender {
[UIView beginAnimations:#"View Curl" context:nil];
[UIView setAnimationDuration:1.00];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
if (self.firstScreen.view.superview ==nil){
if(self.firstScreen==nil) {
self.firstScreen = [[FirstScreen alloc] initWithNibName:#"FirstScreen" bundle:nil];
}
[self.config1.view removeFromSuperview];
[self.view insertSubview:self.firstScreen.view atIndex:0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
[self.config1.view removeFromSuperview];
[self.view insertSubview:self.firstScreen.view atIndex:0];
[sender setTitle:#"Switch To DVR"];
}
else{
if(self.config1 == nil){
self.config1 = [[Config1 alloc] initWithNibName:#"Config1" bundle:nil];
}
[self.firstScreen.view removeFromSuperview];
[self.view insertSubview:self.config1.view atIndex:0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[self.firstScreen.view removeFromSuperview];
[self.view insertSubview:self.config1.view atIndex:0];
[sender setTitle:#"Switch To TV"];
}
[UIView commitAnimations];
}
I want to remove the parent class and have just the two classes.
Is it possible to have a button inside class1 when pushed will take me to class2???
There is a 7 minute tutorial on YouTube Here. That shows how to move from one view to another using a button without storybord so you will be able to lern the code to move from one class to another.
I hope this helps. As for being a beginner if you look around youtube you will find lots of tutorials to help you learn. :)
EDIT: this does not use a navigation controller
i hope This solution helps You
just make object from Class2 and when Button1 Pressed add Class2's object.View as subview to Class1.view
Good Luck
Try something like :
- (IBAction)flipViews {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.6f];
if ([saisieCompleteView superview])
{
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
[saisieCompleteView removeFromSuperview];
[self.view addSubview:saisieRapideView];
[self.view sendSubviewToBack:saisieCompleteView];
}
else {
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[saisieRapideView removeFromSuperview];
[self.view addSubview:saisieCompleteView];
[self.view sendSubviewToBack:saisieRapideView];
}
[UIView commitAnimations];
}
The both saisieCompleteView and saisieRapideView must be subview of your principal view.
you may pop the another view with modal flip transition:
[self presentViewController:Class2 animated:YES completion:^{
// Some code on completeion
}];
to dismiss the Class2 view:
[self dismissViewControllerAnimated:YES completion:^{
//code
}];
if you don't want to go out of current view controller, you may flip it this way:
BOOL toShowSecond = YES;
...
[UIView transitionWithView:self.view
duration:1.0
options:(toShowSecond?UIViewAnimationOptionTransitionFlipFromLeft:UIViewAnimationOptionTransitionFlipFromRight)
animations:^{
if(toShowSecond) {
firstView.hidden = YES;
secondView.hidden = NO;
} else {
firstView.hidden = NO;
secondView.hidden = YES;
}
}
completion:^(BOOL finished){
toShowSecond = !toShowSecond;
}];
I'm trying to work on a UIButton animation where the button moves to a point and then is set hidden to be true. However when I tried working on the following code, the button disappeared even before the animation was completed. Am I doing it correctly? Any suggestions?
[UIView animateWithDuration:0.8
animations:^{
selectedCurveIndex = 0;
[tradebutton moveTo:
CGPointMake(51,150) duration:0.8
option:curveValues[UIViewAnimationOptionCurveEaseInOut]];
}
completion:^(BOOL finished){
[tradeButton setHidden:TRUE];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"ButtonView"];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:vc animated:NO];
}];
You need to make sure that finished is set to YES before moving on.
Your button hides quickly because 0.8 is a quick animation duration. You will need to figure out another place to hide the button, or you can
Try this:
[UIView animateWithDuration:0.8
animations:^{
selectedCurveIndex = 0;
[tradebutton moveTo:
CGPointMake(51,150) duration:0.8
option:curveValues[UIViewAnimationOptionCurveEaseInOut]];
}
completion:^(BOOL finished){
if ( finished )
{
[tradeButton performSelector:#selector(setHidden:) withObject:#"YES" afterDelay:3.0];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"ButtonView"];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:vc animated:NO];
}
}];
The problem is that you create a second, inner animation block in the moveTo:duration:option: method, and you set all of the animatable properties in that inner block. You don't set any animatable properties in the outer block.
That means that the system immediately thinks that the outer animation has finished, and calls the completion block right away. Meanwhile, the inner animation block is still going.
Stop using moveTo:duration:option:. It saves you almost nothing, and ends up giving you trouble like this. Throw it out and try something like this instead:
[UIView animateWithDuration:0.8 animations:^{
tradeButton.frame = (CGRect){ CGPointMake(51, 150), tradeButton.bounds.size };
} completion:^(BOOL finished) {
tradeButton.hidden = YES;
// etc.
}];
Note that UIViewAnimationOptionCurveEaseInEaseOut is the default for most animations.