//
// CZNavigationController.m
// 手势移除控制器
//
// Created by pkxing on 14/12/10.
// Copyright (c) 2014年 梦醒. All rights reserved.
//
// 图片透明度最小值
#define PKMinAlpha 0.5
// 动画时间
#define PKDuration 0.1
// 手势最大速率
#define PKMaxVelocity 800
// 阴影不透明度
#define PKShadowOpacity 0.3
// 阴影偏移量
#define PKShadowOffset CGSizeMake(-3, 0)
// 阴影颜色
#define PKShadowColor [UIColor blackColor].CGColor
#import "CZNavigationController.h"
@interface CZNavigationController()<UINavigationControllerDelegate>
/** 所有控制器截图 */
@property(nonatomic,strong) NSMutableArray *images;
/** 左边显示的 imageView */
@property(nonatomic,strong) UIImageView *imageView;
/** 导航控制器view的宽度 */
@property(nonatomic,assign) CGFloat viewWidth;
/** 子控制器的个数 */
@property(nonatomic,assign) int vcCount;
@end
@implementation CZNavigationController
#pragma mark - 懒加载方法
/**
* 懒加载 imageView。
*/
- (UIImageView *)imageView {
if(_imageView == nil) {
_imageView = [[UIImageView alloc] init];
CGRect frame = self.view.bounds;
frame.origin.x -= frame.size.width;
_imageView.frame = frame;
[self.view insertSubview:_imageView belowSubview:self.navigationBar];
}
return _imageView;
}
- (NSMutableArray *)images {
if (_images == nil) {
_images = [NSMutableArray array];
}
return _images;
}
#pragma mark - 生命周期方法
- (void)viewDidLoad {
[super viewDidLoad];
self.viewWidth = self.view.frame.size.width;
// KVO监听vcCount值的变化
[self addObserver];
// 设置代理
self.delegate = self;
// 添加拖拽手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(draging:)];
[self.view addGestureRecognizer:pan];
}
- (void)dealloc {
[self removeObserver];
}
#pragma mark - KVO 属性监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"vcCount"]) {
[self captureScreenShot];
}
}
- (void)addObserver{
[self addObserver:self forKeyPath:@"vcCount" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
- (void)removeObserver{
[self removeObserver:self forKeyPath:@"vcCount"];
}
#pragma mark - 监听拖拽手势
/**
* 监听拖拽手势
*/
- (void)draging:(UIPanGestureRecognizer *)recognizer{
// 如果导航控制器中只有一个子控制器,则不响应拖拽手势
if (self.viewControllers.count <= 1) return;
// 获得拖拽的位置
CGPoint translationPoint = [recognizer translationInView:self.view];
// 获得水平方法平移的值
CGFloat translationX = translationPoint.x;
// 只能向左拖拽(translationX<0表示往右边拖拽)
if (translationX <= 0){
[self settingTransform:0.0];
return;
}
// 手势结束或手势被取消
if (recognizer.state == UIGestureRecognizerStateEnded
|| recognizer.state == UIGestureRecognizerStateCancelled || recognizer.state == UIGestureRecognizerStatePossible || recognizer.state == UIGestureRecognizerStateFailed) { // 拖拽结束或正在拖拽
// 计算拖拽速度
CGPoint velocity = [recognizer velocityInView:self.view];
// 每秒移动多少个点
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
// 如果拖拽速度大于PKMaxVelocity 或 拖拽距离大于导航控制器view宽度的一半,则出栈
BOOL pop = (magnitude > PKMaxVelocity) || (translationX > self.viewWidth * 0.5);
[UIView animateWithDuration:PKDuration delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
[self settingTransform:(pop ? self.viewWidth :0)];
} completion:^(BOOL finished) {
if (pop) {
[self popViewControllerAnimated:NO];
[self settingTransform:0];
self.vcCount = self.viewControllers.count;
}
[_imageView removeFromSuperview];
_imageView = nil;
}];
} else if(recognizer.state == UIGestureRecognizerStateBegan) { // 开始拖拽
[self.view sendSubviewToBack:self.imageView];
self.topViewController.view.layer.shadowOffset = PKShadowOffset;
self.topViewController.view.layer.shadowColor = PKShadowColor;
self.topViewController.view.layer.shadowOpacity = PKShadowOpacity;
} else { // 正在拖拽
if (self.imageView.image == nil) {
self.imageView.image = [self.images lastObject];
}
// 移动导航控制器的view和imageView
[self settingTransform:translationX];
}
}
/**
* 设置导航控制器和imageView的transform
*/
- (void)settingTransform:(CGFloat)translationX{
self.topViewController.view.layer.transform = CATransform3DMakeTranslation(translationX, 0, 0);
self.imageView.layer.transform = CATransform3DMakeTranslation(translationX, 0, 0);
if (translationX == 0) {
self.topViewController.view.layer.shadowOpacity = 0.0;
self.navigationBar.alpha = 1.0;
} else {
// 控制imageView 的透明度
CGFloat alpha = 1 - (translationX / self.viewWidth);
self.navigationBar.alpha = MAX(0.8, alpha);
}
}
/**
* 屏幕截图
*/
- (void)captureScreenShot{
[self.images removeAllObjects];
int count = self.viewControllers.count;
if (count <= 1) return;
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *controller = self.viewControllers[count - 2];
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, YES, 0.0);
[controller.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.images addObject:image];
});
}
#pragma mark - UINavigationControllerDelegate 方法
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
self.vcCount = self.viewControllers.count;
}
@end
手势移除控制器(UIPanGestureRecognizer + UINavigationController)
猜你喜欢
转载自blog.csdn.net/pkxwyf/article/details/41855489
今日推荐
周排行