最近項(xiàng)目做完了崭别,就進(jìn)入無休止的修改中了树酪。也順便在看swift择镇。學(xué)到了兩個(gè)轉(zhuǎn)場動(dòng)畫压恒,也給大家看看
PS:其實(shí)我一直以為轉(zhuǎn)場動(dòng)畫又難又不實(shí)用影暴,哈哈
轉(zhuǎn)場動(dòng)畫1: (先看效果圖)
這種轉(zhuǎn)場方式跟boss直聘的應(yīng)該差不多怖亭,所有就收集了
先說說建的類的用處吧: ViewController:第一個(gè)控制器 BViewController:push出來的第二個(gè)控制器 PushAnimateion:繼承NSObject的工具類,用于修改push動(dòng)畫 PopAnimateion:繼承NSObject的工具類坤检,用于修改Pop動(dòng)畫
下面給出ViewController里面代碼和PushAnimateion里面具體代碼兴猩,另外兩個(gè)類似,只上截圖早歇。另外倾芝,ViewController的導(dǎo)航欄是在storyboard里面直接加的 ViewController .m:
#import "ViewController.h"
#import "BViewController.h"
#import "PushAnimateion.h"
@interface ViewController ()<UINavigationControllerDelegate>
@end
@implementation ViewController
//這個(gè)控制器的代理一定要在viewWillAppear里面設(shè)置
//因?yàn)槊看蝡ush的時(shí)候控制器不會(huì)dealloc
//所以如果寫在viewDidLoad里面的話在pop回來的時(shí)候就不會(huì)再次執(zhí)行代理,動(dòng)畫就會(huì)失效
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.delegate = self;
}
- (void)viewDidLoad {
[super viewDidLoad];
//設(shè)置背景圖片
self.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"4"].CGImage);
self.navigationController.navigationBar.hidden = YES;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
BViewController *view = [BViewController new];
[self.navigationController pushViewController:view animated:YES];
}
//需要返回的是一個(gè)id類型的且遵循UIViewControllerAnimatedTransitioning協(xié)議的
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC {
//根據(jù)類型返回對(duì)應(yīng)動(dòng)畫
if (operation == UINavigationControllerOperationPush) {
return [PushAnimateion new];
}else {
return nil;
}
}
@end
PushAnimateion里面代碼:
//這是.h里面的箭跳,要遵循這個(gè)協(xié)議晨另,不然UINavigationControllerDelegate返回這個(gè)類的對(duì)象會(huì)報(bào)錯(cuò),所以寫在.h里面
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface PushAnimateion : NSObject<UIViewControllerAnimatedTransitioning>
@end
//.m里面代碼
#import "PushAnimateion.h"
#define WIDTH [UIScreen mainScreen].bounds.size.width
#define HEIGHT [UIScreen mainScreen].bounds.size.height
@interface PushAnimateion ()<CAAnimationDelegate>
@property (nonatomic, retain) id<UIViewControllerContextTransitioning> transitionContext;
@end
@implementation PushAnimateion
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return .5;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
self.transitionContext = transitionContext;
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] addSubview:fromVC.view];
[[transitionContext containerView] addSubview:toVC.view];
UIBezierPath *starPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, HEIGHT*0.5, WIDTH, 1)];
UIBezierPath *endPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, WIDTH, HEIGHT)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
maskLayer.path = endPath.CGPath;
toVC.view.layer.mask = maskLayer;
CABasicAnimation *animate = [CABasicAnimation animationWithKeyPath:@"path"];
animate.fromValue = (__bridge id _Nullable)(starPath.CGPath);
animate.toValue = (__bridge id _Nullable)(endPath.CGPath);
animate.duration = [self transitionDuration:transitionContext];
animate.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animate.delegate = self;
[maskLayer addAnimation:animate forKey:@"path"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
[self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
[self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
[self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
}
@end
如果建的類名相同谱姓,可以直接把代碼拖到項(xiàng)目里借尿,代碼都拷貝齊全的 下面給兩張圖片是BViewController的m文件和PopAnimateion的m文件。PopAnimateion的h文件里跟PushAnimateion里面是一樣的屉来,代碼基本一樣路翻,可以復(fù)制過去直接用
該項(xiàng)目有一點(diǎn)點(diǎn)小bug,就是pop回來的時(shí)候會(huì)閃一下茄靠,求大神解決了告知茂契,??
轉(zhuǎn)場動(dòng)畫2:
這個(gè)效果是系統(tǒng)自帶的動(dòng)畫,做的比較粗糙慨绳,需要使用的朋友可以自己再修復(fù)一下 這個(gè)比較簡單掉冶,直接上代碼然后說一下就好了
rootViewController的.m里面代碼
#import "ViewController.h"
#import "AViewController.h"
#import "BViewController.h"
@interface ViewController ()
@property (nonatomic, assign) NSInteger currentChildNumber;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.currentChildNumber = 0;
[self addChildViewController:[AViewController new]];
[self addChildViewController:[BViewController new]];
[self.view addSubview:self.childViewControllers.firstObject.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getNotification) name:@"push" object:nil];
}
- (void)getNotification {
[self transitionFromViewController:self.currentChildNumber == 0 ? self.childViewControllers.firstObject : self.childViewControllers.lastObject
toViewController:self.currentChildNumber == 1 ? self.childViewControllers.firstObject : self.childViewControllers.lastObject
duration:1
options:self.currentChildNumber == 0 ? UIViewAnimationOptionTransitionFlipFromLeft : UIViewAnimationOptionTransitionFlipFromRight
animations:nil
completion:nil];
self.currentChildNumber = (self.currentChildNumber + 1) % 2;
}
@end
只需要另外新建兩個(gè)控制器,在touchBegin里面發(fā)個(gè)通知脐雪,這里接收就OK
需要代碼的可以加群:515385179(群里都沒有人厌小,來點(diǎn)大神救救我吧??)
我是小白,有沒有收徒的战秋,我報(bào)名??