在一些老项目中,看到了一个点击UITabViewController的tab,左右滑动出现子控制器的转场动画.
虽然是OC写的,但是代码写的还算精简,也比较好用,就先放着这里吧.
.h文件
#import <UIKit/UIKit.h>
@interface Transformer : NSObject <UITabBarControllerDelegate, UIViewControllerAnimatedTransitioning>
@property (assign, nonatomic) NSInteger preIndex;
@property (assign, nonatomic) NSInteger selectedIndex;
@end
.m文件
#import "Transformer.h"
#import "TabBarController.h"
static CGFloat const kPadding = 10;
static CGFloat const kDamping = 0.75;
static CGFloat const kVelocity = 2;
@implementation Transformer
- (instancetype)init {
self = [super init];
if (self) {
_preIndex = 0;
_selectedIndex = 0;
}
return self;
}
#pragma mark- UITabBarControllerDelegate
- (id<UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController animationControllerForTransitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
TabBarController *tabVC = (TabBarController *)tabBarController;
return tabVC.transform;
}
#pragma mark- UIViewControllerAnimatedTransitioning
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 0.5;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
NSLog(@"Animation begin... ... ");
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIView *containerView = [transitionContext containerView];
CGFloat translation = containerView.bounds.size.width + kPadding;
CGAffineTransform transform = CGAffineTransformMakeTranslation(_preIndex > _selectedIndex ? translation : -translation, 0);
toViewController.view.transform = CGAffineTransformInvert(transform);
[containerView addSubview:toViewController.view];
[UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:kDamping initialSpringVelocity:kVelocity options:UIViewAnimationOptionCurveEaseInOut animations:^{
fromViewController.view.transform = transform;
toViewController.view.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
fromViewController.view.transform = CGAffineTransformIdentity;
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
使用
在UITabViewController的子类中
.h文件
#import <UIKit/UIKit.h>
@class Transformer;
@interface TabBarController : UITabBarController
@property (nonatomic, strong) UIView *snapShot;
@property (strong, nonatomic) Transformer *transform;
@end
.m文件
#import "TabBarController.h"
#import "AppDelegate.h"
#import "Transformer.h"
@interface TabBarController ()
@end
@implementation TabBarController
- (void)viewDidLoad {
[super viewDidLoad];
// 添加转场动画的代理
self.transform = [[Transformer alloc] init];
self.delegate = self.transform;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
weakifySelf
self.snapShot.frame = self.view.bounds;
[self.view addSubview:self.snapShot];
[UIView animateWithDuration:1 animations:^{
strongifySelf
self.snapShot.transform = CGAffineTransformScale(CGAffineTransformIdentity, 5, 5);
self.snapShot.alpha = 0;
} completion:^(BOOL finished) {
strongifySelf
[self.snapShot removeFromSuperview];
}];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// 用于设置tabbar itemz中的tag
for (NSInteger i = 0; i < self.childViewControllers.count; i++) {
[self.tabBar.items[i] setTag:i];
}
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[[NSUserDefaults standardUserDefaults] setBool:true forKey:@"didShowTab"];
[[NSUserDefaults standardUserDefaults] synchronize];
[appDelegate startTimer];
}
#pragma mark- UITabBarDelegate
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
self.transform.selectedIndex = item.tag;
self.transform.preIndex = self.selectedIndex;
}
@end