Initial commit

This commit is contained in:
ifish
2017-08-15 16:59:01 +08:00
commit bdc83e07ef
5766 changed files with 423223 additions and 0 deletions
@@ -0,0 +1,39 @@
//
// NTESNavigationAnimator.h
// NIM
//
// Created by chris on 16/1/31.
// Copyright © 2016年 Netease. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, NTESNavigationAnimationType) {
NTESNavigationAnimationTypeNormal,
NTESNavigationAnimationTypeCross,
};
@class NTESNavigationAnimator;
@protocol NTESNavigationAnimatorDelegate <NSObject>
- (void)animationWillStart:(NTESNavigationAnimator *)animator;
- (void)animationDidEnd:(NTESNavigationAnimator *)animator;
@end
@interface NTESNavigationAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic,weak) UINavigationController *navigationController;
@property (nonatomic,assign) UINavigationControllerOperation currentOpearation;
@property (nonatomic,assign) NTESNavigationAnimationType animationType;
@property (nonatomic,weak) id<NTESNavigationAnimatorDelegate> delegate;
- (instancetype)initWithNavigationController:(UINavigationController *)navigationController;
@end
@@ -0,0 +1,150 @@
//
// NTESNavigationAnimator.m
// NIM
//
// Created by chris on 16/1/31.
// Copyright © 2016年 Netease. All rights reserved.
//
#import "NTESNavigationAnimator.h"
#import "UIView+NTES.h"
//#import "NTESMainTabController.h"
#import "IfishMianTabViewController.h"
@implementation NTESNavigationAnimator
- (instancetype)initWithNavigationController:(UINavigationController *)navigationController
{
self = [super init];
if (self) {
_navigationController = navigationController;
}
return self;
}
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.35;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
switch (self.currentOpearation) {
case UINavigationControllerOperationPop:
[self popAnimation:transitionContext];
break;
case UINavigationControllerOperationPush:
[self pushAnimation:transitionContext];
break;
default:
break;
}
}
- (void)pushAnimation:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIView *containerView = [transitionContext containerView];
UINavigationController *navigationController = fromViewController.navigationController;
UITabBarController *tabbarController = fromViewController.tabBarController;
//使用xib可能会出现view的size不对的情况
CGRect frame = fromViewController.view.frame;
if ((toViewController.edgesForExtendedLayout & UIRectEdgeTop) == 0)
{
frame = CGRectOffset(navigationController.view.frame, 0, navigationController.navigationBar.bottom);
}
if ((toViewController.edgesForExtendedLayout & UIRectEdgeBottom) == 0) {
CGRect slice = CGRectZero;
CGRect remainder = CGRectZero;
CGRectDivide(frame, &slice, &remainder, tabbarController.tabBar.height, CGRectMaxYEdge);
frame = remainder;
}
toViewController.view.frame = frame;
[containerView addSubview:fromViewController.view];
[containerView addSubview:toViewController.view];
CGFloat width = containerView.width;
toViewController.view.left = width;
[self callAnimationWillStart];
CGFloat duration = [self transitionDuration:transitionContext];
[UIView animateWithDuration:duration animations:^{
fromViewController.view.right = width * 0.5;
toViewController.view.right = width;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
[self callAnimationDidEnd];
}];
}
- (void)popAnimation:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
CGFloat snapshootHeight = [UIApplication sharedApplication].statusBarFrame.size.height + fromViewController.navigationController.navigationBar.height;
UIView *fakeBar = [fromViewController.navigationController.view
resizableSnapshotViewFromRect:CGRectMake(0, 0,fromViewController.view.width, snapshootHeight) afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];
UINavigationBar *tureBar = toViewController.navigationController.navigationBar;
BOOL hidesBottomBar = toViewController.hidesBottomBarWhenPushed && self.navigationController.viewControllers.firstObject != toViewController;
UITabBar *tabbar = [IfishMianTabViewController instance].tabBar;
UIView *containerView = [transitionContext containerView];
[containerView addSubview:toViewController.view];
if (!hidesBottomBar) {
[containerView addSubview:tabbar];
}
if (self.animationType == NTESNavigationAnimationTypeCross) {
[containerView addSubview:tureBar];
[fromViewController.view addSubview:fakeBar];
}
[containerView addSubview:fromViewController.view];
CGFloat width = containerView.width;
toViewController.view.right = width * 0.5;
tabbar.right = width * 0.5;
[self callAnimationWillStart];
CGFloat duration = [self transitionDuration:transitionContext];
[UIView animateWithDuration:duration animations:^{
fromViewController.view.left = width;
toViewController.view.right = width;
tabbar.right = width;
fakeBar.alpha = 0.0;
} completion:^(BOOL finished) {
[[IfishMianTabViewController instance].view addSubview:tabbar];
[toViewController.navigationController.view addSubview:tureBar];
[fakeBar removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
[self callAnimationDidEnd];
}];
}
- (void)callAnimationWillStart
{
if ([self.delegate respondsToSelector:@selector(animationWillStart:)]) {
[self.delegate animationWillStart:self];
}
}
- (void)callAnimationDidEnd
{
if ([self.delegate respondsToSelector:@selector(animationDidEnd:)]) {
[self.delegate animationDidEnd:self];
}
}
@end
@@ -0,0 +1,17 @@
//
// NTESNavigationHandler.h
// NIM
//
// Created by chris on 16/1/28.
// Copyright © 2016年 Netease. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NTESNavigationHandler : NSObject<UINavigationControllerDelegate>
@property (nonatomic,strong,readonly) UIPanGestureRecognizer *recognizer;
- (instancetype)initWithNavigationController:(UINavigationController *)navigationController;
@end
@@ -0,0 +1,185 @@
//
// NTESNavigationHandler.m
// NIM
//
// Created by chris on 16/1/28.
// Copyright © 2016年 Netease. All rights reserved.
//
#import "NTESNavigationHandler.h"
#import "UIView+NTES.h"
//#import "NTESMainTabController.h"
#import "IfishMianTabViewController.h"
#import "UIResponder+NTESFirstResponder.h"
#import "NTESNavigationAnimator.h"
@interface NTESNavigationHandler()<UIGestureRecognizerDelegate,NTESNavigationAnimatorDelegate>
@property (nonatomic,strong) UIPercentDrivenInteractiveTransition* interaction;
@property (nonatomic,weak) UINavigationController *navigationController;
@property (nonatomic,strong) NTESNavigationAnimator *animator;
@property (nonatomic,assign) UINavigationControllerOperation currentOperation;
@property (nonatomic,strong) CAGradientLayer *uiPopShadow;
@property (nonatomic,assign) BOOL isAnimating;
@end
@implementation NTESNavigationHandler
- (instancetype)initWithNavigationController:(UINavigationController *)navigationController
{
self = [super init];
if (self) {
_recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
_recognizer.delegate = self;
_recognizer.delaysTouchesBegan = NO;
[navigationController.view addGestureRecognizer:_recognizer];
_animator = [[NTESNavigationAnimator alloc] initWithNavigationController:navigationController];
_animator.delegate = self;
_navigationController = navigationController;
}
return self;
}
- (void)pan:(UIPanGestureRecognizer*)recognizer
{
UIView* view = recognizer.view;
switch (recognizer.state) {
case UIGestureRecognizerStateBegan:{
CGPoint location = [recognizer locationInView:view];
if (location.x < CGRectGetMidX(view.bounds) && self.navigationController.viewControllers.count > 1) { // left half
self.interaction = [UIPercentDrivenInteractiveTransition new];
[self.navigationController popViewControllerAnimated:YES];
}
}
break;
case UIGestureRecognizerStateChanged:{
CGPoint translation = [recognizer translationInView:view];
CGFloat d = translation.x / view.width;
[self.interaction updateInteractiveTransition:d];
}
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:{
if ([recognizer locationInView:view].x > view.width * .5f) {
[self.interaction finishInteractiveTransition];
} else {
[self.interaction cancelInteractiveTransition];
}
self.interaction = nil;
}
break;
default:
break;
}
}
#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
}
- (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController
{
return self.interaction;
}
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
self.currentOperation = operation;
self.animator.currentOpearation = operation;
BOOL cross = [self isUseClearBar:fromVC] || [self isUseClearBar:toVC];
self.animator.animationType = cross ? NTESNavigationAnimationTypeCross : NTESNavigationAnimationTypeNormal;
if (operation == UINavigationControllerOperationPop) {
[fromVC.view.layer addSublayer:self.uiPopShadow];
}
return self.animator;
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
BOOL forbid = [self isForbidInteractivePop:self.navigationController.topViewController];
if (forbid || self.isAnimating) {
return NO;
}
UIView* view = gestureRecognizer.view;
CGPoint location = [gestureRecognizer locationInView:view];
return location.x < 44.f;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(nonnull UIGestureRecognizer *)otherGestureRecognizer
{
return [otherGestureRecognizer.view.superview isKindOfClass:[UITableView class]];
}
#pragma mark - Get
- (CAGradientLayer *)uiPopShadow
{
if (!_uiPopShadow) {
_uiPopShadow = [CAGradientLayer layer];
_uiPopShadow.frame = CGRectMake(-6, 0, 6, [IfishMianTabViewController instance].view.frame.size.height);
_uiPopShadow.startPoint = CGPointMake(1.0, 0.5);
_uiPopShadow.endPoint = CGPointMake(0, 0.5);
_uiPopShadow.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.2f] CGColor], (id)[[UIColor clearColor] CGColor], nil];
}
return _uiPopShadow;
}
#pragma mark - NTESNavigationAnimatorDelegate
- (void)animationWillStart:(NTESNavigationAnimator *)animator
{
self.isAnimating = YES;
}
- (void)animationDidEnd:(NTESNavigationAnimator *)animator
{
self.isAnimating = NO;
}
#pragma mark - Private
- (BOOL)isUseClearBar:(UIViewController *)vc
{
SEL sel = NSSelectorFromString(@"useClearBar");
BOOL use = NO;
if ([vc respondsToSelector:sel]) {
SuppressPerformSelectorLeakWarning(use = (BOOL)[vc performSelector:sel]);
}
return use;
}
- (BOOL)isForbidInteractivePop:(UIViewController *)vc{
SEL sel = NSSelectorFromString(@"forbidInteractivePop");
BOOL use = NO;
if ([vc respondsToSelector:sel]) {
SuppressPerformSelectorLeakWarning(use = (BOOL)[vc performSelector:sel]);
}
return use;
}
@end