how can i switch between two views using CATransition? - ios

I have implemented in my code today a CATransition of type cube,
as I seen here, CATransition can be added to self.view.layer,
so my first question is if I can use my CATransition for switching between viewControllers and not just UIViews?
if I can't do it,
please look at this image:
http://up411.siz.co.il/up1/hnmim2mtjodt.png
as you can see, while the transition is in process, I see the same view of both faces of the cube,
I'd like it to be that one face presents view A and the other one presents view B
here is the code if needed :
self.view.layer.addAnimation(createTransition("Right"), forKey: "kCATransition")
func createTransition(side:String) -> CATransition{
var transition = CATransition()
transition.delegate = self
transition.duration = 0.6
transition.timingFunction = CAMediaTimingFunction(name: "easeInEaseOut")
transition.type = "cube"
transition.subtype = "from\(side)"
return transition
}

You have to add the same transition to the view layer of the second view controller's view as well.
Apple documentation in the Core Animation Programming Guide:
To perform a transition animation, you create a CATransition object and add it to the layers involved in the transition.

Related

How can I create a transition between two subview iOS?

I have a problem when I want to create a transition between to views inside a container view in iOS application. I want to create an animation that makes my first view goes out sliding to the left and the second coming from the right (like switching between photos, a sort of push in Navigation Controller). I created my animation but the problem is that my subview does not disappear once reached the border of my container view but when it reaches the edge of my screen.
I used this code:
CATransition *transition = [CATransition animation];
transition.duration = animationTime;
transition.type = kCATransitionPush;
transition.subtype = transationSubtype;
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
transition.removedOnCompletion = YES;
[view.layer addAnimation:transition forKey:nil];
As visible in the image the red square goes out from the screen and not from its container and also the green comes inside from the screen edge and not from the container view edge. I want instead that the animation ends when reaches the container view edge.
I tried anything but I was not able to find something useful.
Try to set clipsToBounds property of the container view to YES

How to create a "scrolling-sliding" transition between two child controllers

I am trying to slide between two child controllers that get loaded into a container view. I have found out about the sliding effect in CATransition. However, it doesn't slide the way I want it to. If I am sliding from right to left, I want the current controller to also slide to the left. So, it basically creates a scrolling effect using sliding. How can I achieve that? Here is my current code.
var transition = CATransition();
transition.duration = 0.25;
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut);
transition.type = kCATransitionPush
if source.prevItem > source.pageControl.currentPage {
transition.subtype = kCATransitionFromLeft
} else {
transition.subtype = kCATransitionFromRight
}
dest.view.layer.addAnimation(transition, forKey: kCATransition)
source.transitionFromViewController(
source.currentChildController!,
toViewController: dest,
duration: 0.5,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: nil,
completion: { finished in
source.currentChildController?.removeFromParentViewController()
dest.didMoveToParentViewController(source)
source.currentChildController = dest
}
);
This implementation only brings the destination controller over the current controller even though the documentation for Push transition states: "The layer’s content pushes any existing content as it slides into place. The “Common Transition Subtypes” are used with this transition."

UINavigationController Custom CATransition

I am trying to make a custom transition to push a view controller into the stack.
I dont know if there is an easy way to "lock" the navigationBar on its position and make the transition under the navigationBar.
I am using the following code:
CATransition *transition = [CATransition animation];
transition.duration = 0.3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromBottom;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
First I tried the kCATransitionPush, but I could see the navigationBar moving down... so I tested kCATransitionMoveIn and it feels a bit better, but still not the way I wanted...
Is there a simple way to achieve this?
What you're doing is not how you do custom navigation controller transitions. You have to use the iOS 7 custom animator protocols (e.g. UIViewControllerAnimatedTransitioning).

How to animate view after using UIModalPresentationCurrentContext

I was looking around for a solution on how to wrap a view in a dialog in iOS when I came across this post, which has this line:
vc.modalPresentationStyle = UIModalPresentationCurrentContext;
It solves my problem of basically creating/imitating a dialog but it does not animate upon transition as mentioned in the post. So what is the simplest way to get the slide up animation?
ps.I would ask this as a sub question in that post but I do not have 50 rep comment :(
Well, once your view has been shown, you can do pretty much any animation you want in it. You can do a simple [UIView animateWithDuration] kind of deal, but I would personally use a CATransition for this, it's relatively simple.
The Way of the QuartzCore
First, I'm gonna assume that the view you're presenting is transparent, and there's another view inside that behaves as the dialog. The view controller that will be presented, let's call it PresentedViewController and holds the dialog property for the view within.
PresentedViewController.m
(Needs to be link against QuartzCore.h)
#import <QuartzCore/QuartzCore.h>
#implementation PresentedViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (animated)
{
CATransition *slide = [CATransition animation];
slide.type = kCATransitionPush;
slide.subtype = kCATransitionFromTop;
slide.duration = 0.4;
slide.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
slide.removedOnCompletion = YES;
[self.dialog.layer addAnimation:slide forKey:#"slidein"];
}
}
Getting Fancy
The good thing about this, is that you can create your own custom animations, and play around with other properties.
CABasicAnimation *animations = [CABasicAnimation animationWithKeyPath:#"transform"];
CATransform3D transform;
// Take outside the screen
transform = CATransform3DMakeTranslation(0, self.view.bounds.size.height, 0);
// Rotate it
transform = CATransform3DRotate(transform, M_PI_4, 0, 0, 1);
animations.fromValue = [NSValue valueWithCATransform3D:transform];
animations.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
animations.duration = 0.4;
animations.fillMode = kCAFillModeForwards;
animations.removedOnCompletion = YES;
animations.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0 :0.0 :0 :1];
[self.dialog.layer addAnimation:animations forKey:#"slidein"];
Here, the view will be moved outside of screen by the translation, then rotated, and it will slide in, back to its original transform. I also modified the timing function to provide a smoother curve.
Consider that I just scraped the surface of what's possible with CoreAnimation, I've been on this road for three years now, and I've grown to like CAAnimation for all the things it does.
Storyboard pro-tip: You can wrap this up very nicely if you build your own custom UIStoryboardSegue subclass.

Anyway to remove fade when using CATransition between 2 views?

What I'm trying to do is push in from the left side with a custom animation using CATransitions. In my normal code I want to use duration of 0.3, but in the example below I'm using 6.0 just so I can see the actual problem during the transition.
And it is really obvious that there is a fade going on when transitioning to the new view. The new view coming in fades from it's background color to the actual view, whereas the view that is sliding off screen fades from the actual view to it's background color. It's making for some odd looks when doing the push animation to transition.
Below is the code that I'm using for the transition. settingsController is the controller I'm trying to animate to.
let transition = CATransition()
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 6.0
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
self.navigationController?.view.layer.addAnimation(transition, forKey: nil)
UIView.transitionFromView(self.view, toView: settingsViewController.view, duration: 0, options: UIViewAnimationOptions.TransitionNone, completion: nil)
self.navigationController?.pushViewController(settingsViewController, animated: false)
And as mentioned, the actual sliding animation works as I want it to, however there is this fade that happens that just makes it not look right . I've been searching google and stackoverflow and have not seen a solution posted, so I'm wondering if anyone has any idea how to get rid of this fade, or even if there is a work around that "simulates" this behavior so the user experience looks as I want it to.
I've tried making the background colors of both views the same and it still doesn't look right.
The usual way to use a sliding CATransition is to give the transitioning view/layer a superview that clips to bounds (or a superlayer that masks to bounds). That way, the sliding view/layer is not visible outside the superview's bounds, and we never see the fade.

Resources