I had written transition animation code for UIView but this code is use in multiple screen so all the time I am writing the same code but I want to create class or function so I can easily call this wherever required but I am new in iOS so please help me how to create function and calling in UIView..
CATransition *trans = [CATransition animation];
trans.duration = 0.5;
trans.type = kCATransitionPush;
trans.subtype = kCATransitionFromTop;
[trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[self.container_view.layer trans forKey:nil];
thanks in advance
Create AppFunction class like this:
1. Header File
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface AppFunctions : NSObject
+ (void) animateView:(UIView *)view;
#end
2. Implementation File
#import "AppFunctions.h"
#implementation AppFunctions
+ (void) animateView:(UIView *) view
{
CATransition *trans = [CATransition animation];
trans.duration = 0.5;
trans.type = kCATransitionPush;
trans.subtype = kCATransitionFromTop;
[trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[view.layer addAnimation:trans forKey:nil];
}
#end
Now call Like this where you want by importing #import "AppFunctions.h"
[AppFunctions animateView:self.view];
call this method like this
- (void)viewDidLoad{
[super viewDidLoad];
[self animate:self.view];}
here is your funcation
-(void)animate:(UIView *)view{
CATransition *trans = [CATransition animation];
trans.duration = 0.5;
trans.type = kCATransitionPush;
trans.subtype = kCATransitionFromTop;
[trans setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[self.container_view.layer trans forKey:nil];}
Related
I am animating a UILabel to 'evaporate' off the screen using CATransition.
I want the label text to turn green, and move off the screen.
The following code does 'evaporate' the label fine, but doesn't change its colour before animating:
CATransition *transition = [CATransition animation];
transition.beginTime = CACurrentMediaTime();
transition.duration = 0.4;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromTop;
[self.displayLabel.layer addAnimation:transition forKey:#"evaporate"];
self.displayLabel.textColor = [self greenColor];
self.displayLabel.text = #" ";
Calling setNeedsDisplay on the label doesn't work.
Can't use a CABasicAnimation because the label text is changing.
What am I doing wrong and how do I fix it?
You basically want nested animations or, in a sense, looking for a completion block type thing.
The closest I can think of achieving this is by using the CATransition delegate
Example:
-(IBAction)btnTest:(UIButton *)sender
{
//[1] Animate text color change
CATransition *animation = [CATransition animation];
[animation setDelegate:self]; //important
[animation setRemovedOnCompletion:YES]; //better to remove the animation
[animation setBeginTime:CACurrentMediaTime()]; //not really needed
[animation setDuration:0.4];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
[animation setType:kCATransitionFade];
//you can specify any key name or keep it nil. doesn't make a difference
[self.displayLabel.layer addAnimation:animation forKey:#"changeTextColor"];
[self.displayLabel setTextColor:[UIColor greenColor]];
}
#pragma mark - CATransition Delegate
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
//[2] Animate text sublayer
/*
The following CATransition should not set a delegate
otherwise this animation will loop continously
*/
CATransition *animation = [CATransition animation];
[animation setRemovedOnCompletion:YES]; //better to remove the animation
[animation setBeginTime:CACurrentMediaTime()]; //not really needed
[animation setDuration:0.4];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromTop];
//you can specify any key name or keep it nil. doesn't make a difference
[self.displayLabel.layer addAnimation:animation forKey:#"changeText"];
[self.displayLabel setText:#" "];
}
I have two blocks of code (described also in another topic)
- (void)AnimateImage:(NSString*)direction{
self.CurrentAnimal.image = [images objectAtIndex:image_nr];
CATransition *animation = [CATransition animation];
[animation setDuration:1.0];
[animation setType:kCATransitionPush];
if([direction isEqualToString:#"left"]){
[animation setSubtype:kCATransitionFromLeft];
}
else {
[animation setSubtype:kCATransitionFromRight];
}
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
[[self.CurrentAnimal layer] addAnimation:animation forKey:nil];
}
And
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
//do what you need to do when animation ends...
}
I know that I need to "set the delegate property and implement the method" to catch animationDidStop event but I'm not able to get it working.
Question - How do I set up my .h and .m files so that I'm able to use this method to execute code when CATransition animation stops?
Set up the delegate:
CATransition *animation = [CATransition animation];
....
[animation setDelegate:self];
[animation setDuration:1.0];
[animation setType:kCATransitionPush];
You first have to add the Delegate to the CATransition object you created like that
CATransition *animation = [CATransition animation];
[animation setDelegate = self];
[animation setValue:animation.values.lastObject forKey:#"myAnimationKey"];
If you set a key for your animation, you can exactly check which animation ended. If you have just one animation, you don't need a specific key. If you set a key you can check which animation ended like that:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
if(anim == [animation.layer animationForKey:#"myAnimationKey"]){
}
}
How can I get the following animation to work in blocks?
(I need the keyboard to dissappear in the completion handler of the transition animation)
- (void) showNewViewAnimatedSlideAscending:(BOOL)isAscending {
UIView * oldView = self.myView;
UIView * newView = self.myView;
UIView * superView = self.myView.superview;
[oldView removeFromSuperview];
[superView addSubview:newView];
// set up an animation for the transition between the views
CATransition *animation = [CATransition animation];
[animation setDuration:0.3];
[animation setType:kCATransitionPush];
if(isAscending) {
[animation setSubtype:kCATransitionFromRight];
} else {
[animation setSubtype:kCATransitionFromLeft];
}
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[superView layer] addAnimation:animation forKey:#"myTransitionAnimation"];
if(self.keyboardVisible) {
[self.view endEditing:YES];
}
}
p.s; I know, I'm removing and showing the same view. This view has received new data just before calling this method. Somehow the view displays correctly and only shows the new data in the 'new' view.
There are another custom UIViewController transition than the 4 natives iOS:
typedef enum {
UIModalTransitionStyleCoverVertical = 0,
UIModalTransitionStyleFlipHorizontal,
UIModalTransitionStyleCrossDissolve,
UIModalTransitionStylePartialCurl,
} UIModalTransitionStyle;
Any tips?
You could also try CATransition, for example, the code below shows a transition where a second view pushes your current view out to the right. (Assuming this code is placed in your main view controller).
UIView *appWindow = [self.view superview];
CATransition *animation = [CATransition animation];
[animation setDuration:0.3];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[appWindow addSubview:yourSecondViewController.view];
[self.view removeFromSuperview];
[[appWindow layer] addAnimation:animation forKey:#"showSecondViewController"];
How to implement SplitViewController on second level.
Actually what i want is to launch app with a login page and after login. I need SplitViewController.
This is how I do it. By removing the first viewContorller from the window and replacing it with the splitView
splitViewController = [[SplitViewController alloc]init];
// remove the current view and replace with splitViewController
[theWindow addSubview:splitViewController.view];
// Transition handling
NSString *subtypeDirection;
switch ([[UIApplication sharedApplication] statusBarOrientation]) {
case UIDeviceOrientationPortrait:subtypeDirection = kCATransitionFromRight;break;
case UIDeviceOrientationPortraitUpsideDown:subtypeDirection = kCATransitionFromLeft;break;
case UIDeviceOrientationLandscapeLeft:subtypeDirection = kCATransitionFromTop;break;
case UIDeviceOrientationLandscapeRight:subtypeDirection = kCATransitionFromBottom;break;
default: NSLog(#"break at subType direction");break;
}
CATransition *animation = [CATransition animation];
[animation setDuration:.5];
[animation setType:kCATransitionPush];
[animation setSubtype:subtypeDirection];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[theWindow layer] addAnimation:animation forKey:#"SwitchToSplitView"];
[self.navigationController.view removeFromSuperview];
Most of the lines here deals with transition and handling rotation.
self refers to the first ViewController whereas theWindow refers to application window. You can get to it by:[self superView];
For the same login -> splitview controller I'm doing the following:
a. Subclass UIStoryboardSegue and override perform:
#implementation SSPushSegue
- (void)perform
{
UIWindow* window = [self.sourceViewController view].window;
// Transition handling
NSString *subtypeDirection = kCATransitionFromRight;
switch ([UIApplication sharedApplication].statusBarOrientation)
{
case UIDeviceOrientationPortraitUpsideDown: subtypeDirection = kCATransitionFromLeft; break;
case UIDeviceOrientationLandscapeLeft: subtypeDirection = kCATransitionFromTop; break;
case UIDeviceOrientationLandscapeRight: subtypeDirection = kCATransitionFromBottom; break;
default: break;
}
CATransition *animation = [CATransition animation];
animation.duration = .5;
animation.type = kCATransitionPush;
animation.subtype = subtypeDirection;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[window.layer addAnimation:animation forKey:NSStringFromClass([self class])];
window.rootViewController = self.destinationViewController;
}
#end
b. Add "Custom Segue" from Initial View Controller to Destination and put your subclass name in the property field.