最近项目做完了,就进入无休止的修改中了。也顺便在看swift。学到了两个转场动画,也给大家看看
PS:其实我一直以为转场动画又难又不实用,哈哈
转场动画1: (先看效果图)
这种转场方式跟boss直聘的应该差不多,所有就收集了
先说说建的类的用处吧: ViewController:第一个控制器 BViewController:push出来的第二个控制器 PushAnimateion:继承NSObject的工具类,用于修改push动画 PopAnimateion:继承NSObject的工具类,用于修改Pop动画
下面给出ViewController里面代码和PushAnimateion里面具体代码,另外两个类似,只上截图。另外,ViewController的导航栏是在storyboard里面直接加的 ViewController .m:
#import "ViewController.h"
#import "BViewController.h"
#import "PushAnimateion.h"
@interface ViewController ()<UINavigationControllerDelegate>
@end
@implementation ViewController
//这个控制器的代理一定要在viewWillAppear里面设置
//因为每次push的时候控制器不会dealloc
//所以如果写在viewDidLoad里面的话在pop回来的时候就不会再次执行代理,动画就会失效
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.delegate = self;
}
- (void)viewDidLoad {
[super viewDidLoad];
//设置背景图片
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];
}
//需要返回的是一个id类型的且遵循UIViewControllerAnimatedTransitioning协议的
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC {
//根据类型返回对应动画
if (operation == UINavigationControllerOperationPush) {
return [PushAnimateion new];
}else {
return nil;
}
}
@end
PushAnimateion里面代码:
//这是.h里面的,要遵循这个协议,不然UINavigationControllerDelegate返回这个类的对象会报错,所以写在.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
如果建的类名相同,可以直接把代码拖到项目里,代码都拷贝齐全的 下面给两张图片是BViewController的m文件和PopAnimateion的m文件。PopAnimateion的h文件里跟PushAnimateion里面是一样的,代码基本一样,可以复制过去直接用
该项目有一点点小bug,就是pop回来的时候会闪一下,求大神解决了告知,😄
转场动画2:
这个效果是系统自带的动画,做的比较粗糙,需要使用的朋友可以自己再修复一下 这个比较简单,直接上代码然后说一下就好了
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
只需要另外新建两个控制器,在touchBegin里面发个通知,这里接收就OK
需要代码的可以加群:515385179(群里都没有人,来点大神救救我吧😄)
我是小白,有没有收徒的,我报名😂