<span style="background-color: rgb(255, 255, 255);"><span style="font-family:FangSong_GB2312;font-size:18px;"><strong><img alt="难过" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/sad.gif" />以前看别人写 手势滑动返回动画 总是出现各种bug 经过自己修改几乎能满足所有的开发需求</strong></span></span>
1.首先来看下头文件实现
(没得什么变化)
<span style="color:#993300;">#define KEY_WINDOW [[UIApplication sharedApplication]keyWindow]
#define kkBackViewHeight [UIScreen mainScreen].bounds.size.height
#define kkBackViewWidth [UIScreen mainScreen].bounds.size.width
#define iOS7 ( [[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending )
#define lengthForT UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone?150:200
#define windowHeitht UIWindow *screenWindow = [[UIApplication sharedApplication] keyWindow]
// 背景视图起始frame.x
#define startX -200;</span>
<span style="color:#ff0000;">@interface</span> BABaseNavController : UINavigationController
{
CGFloat startBackViewX;
}
<span style="color:#ff0000;">@property (nonatomic,strong)</span><span style="color:#6666cc;">UIPanGestureRecognizer</span> *recognizer; //方便随时关闭手势达到有些界面不准用户手势返回
<span style="color:#ff0000;">@property (nonatomic,retain)</span> <span style="color:#6666cc;">UIView</span> *backgroundView;
<span style="color:#ff0000;">@property (nonatomic,strong)</span> <span style="color:#6666cc;">NSMutableArray</span> *screenShotsList;
<span style="color:#ff0000;">@property (nonatomic,assign)</span> <span style="color:#ff0000;">BOOL</span> isMoving;
// 默认为特效开启
<span style="color:#ff0000;">@property (nonatomic, assign)</span> <span style="color:#ff0000;">BOOL</span> canDragBack;<span style="color:#ff6666;">
</span>
2.来看看如何实现的吧
a. 初始化
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
NSMutableArray * newArr = [[NSMutableArray alloc]init];
self.screenShotsList = newArr; //存放上一个界面截图数组
self.canDragBack = YES;
weighForScreen = Screen_WIDTH; //<span style="font-family: Arial, Helvetica, sans-serif;">weighForScreen是</span>设备的宽度
// [self setup];//自己对<span style="font-family: Arial, Helvetica, sans-serif;">UINavigationController 一些设置</span>
}
return self;
}
b.添加阴影背景和手势设置
- (void)viewDidLoad
{
[super viewDidLoad];
UIImageView *shadowImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"leftside_shadow_bg"]];
shadowImageView.frame = CGRectMake(-10, 0, 10, self.view.frame.size.height);
[self.view addSubview:shadowImageView];
}
-(UIPanGestureRecognizer *)recognizer{
if (!_recognizer) {
_recognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self
action:@selector(paningGestureReceive:)];
[_recognizer delaysTouchesBegan];
[self.view addGestureRecognizer:_recognizer];
}
return _recognizer;
}
c.重写push和pop 方法
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
UIImage * img = [self capture];
if (img == nil) {
img = [[UIImage alloc]init];
}
[self.screenShotsList addObject:img];
if (self.viewControllers.count == 0) {
[self.recognizer setEnabled:NO]; //这里我是按自己需求进行手势的打开与关闭。ps:可以在这里隐藏bar 在pop 显示bar
}else{
[self.recognizer setEnabled:YES];
}
[super pushViewController:viewController animated:animated];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
if (self.viewControllers.count == 2) {
[self.recognizer setEnabled:NO];//同理
}
[self.screenShotsList removeLastObject];
return [super popViewControllerAnimated:animated];
}
d.截屏
- (UIImage *)capture
{
//这里是截取当前window 的屏幕
UIWindow *screenWindow = [[UIApplication sharedApplication] keyWindow];
// UIGraphicsBeginImageContextWithOptions(screenWindow.frame.size, self.view.opaque, 0.0);
UIGraphicsBeginImageContext(screenWindow.size);
[screenWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
e.核心代码手势
#pragma mark - Gesture Recognizer -
- (void)paningGestureReceive:(UIPanGestureRecognizer *)recoginzer
{
if (self.viewControllers.count <= 1 || !self.canDragBack) return;
CGPoint touchPoint = [recoginzer locationInView:KEY_WINDOW];
if (recoginzer.state == UIGestureRecognizerStateBegan) {
_isMoving = YES;
startTouch = touchPoint;
[self.backgroundView removeFromSuperview];
self.backgroundView = nil;
blackMask = nil;
CGRect frame = [UIScreen mainScreen].bounds;
self.backgroundView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width , frame.size.height)];
[self.view.superview insertSubview:self.backgroundView belowSubview:self.view];
blackMask = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width , frame.size.height)];
blackMask.backgroundColor = [UIColor blackColor];
[self.backgroundView addSubview:blackMask];
self.backgroundView.hidden = NO;
if (lastScreenShotView){
[lastScreenShotView removeFromSuperview];
lastScreenShotView = nil;
}
lastScreenShot = [self.screenShotsList lastObject];
lastScreenShotView = [[UIImageView alloc]initWithImage:lastScreenShot];
startBackViewX = startX;
[lastScreenShotView setFrame:CGRectMake(startBackViewX,
lastScreenShotView.frame.origin.y,
lastScreenShotView.frame.size.height,
lastScreenShotView.frame.size.width)];
[self.backgroundView insertSubview:lastScreenShotView belowSubview:blackMask];
}else if (recoginzer.state == UIGestureRecognizerStateEnded){
int cont = 50;
if (touchPoint.x - startTouch.x > cont)
{
[UIView animateWithDuration:0.3 animations:^{
[self moveViewWithX:weighForScreen];
} completion:^(BOOL finished) {
CGRect frame = self.view.frame;
frame.origin.x = 0;
self.view.frame = frame;
_isMoving = NO;
[self popViewControllerAnimated:NO];
}];
}
else
{
[UIView animateWithDuration:0.3 animations:^{
[self moveViewWithX:0];
} completion:^(BOOL finished) {
_isMoving = NO;
self.backgroundView.hidden = YES;
}];
}
return;
}else if (recoginzer.state == UIGestureRecognizerStateCancelled){
[UIView animateWithDuration:0.3 animations:^{
[self moveViewWithX:0];
} completion:^(BOOL finished) {
_isMoving = NO;
self.backgroundView.hidden = YES;
}];
return;
}
if (_isMoving) {
[self moveViewWithX:touchPoint.x - startTouch.x];
}
}
- (void)moveViewWithX:(float)x
{
x = x>weighForScreen?weighForScreen:x;
x = x<0?0:x;
CGRect frame = self.view.frame;
frame.origin.x = x;
self.view.frame = frame;
float alpha = 0.4 - (x/800);
blackMask.alpha = alpha;
CGFloat aa = abs(startBackViewX)/kkBackViewWidth;
CGFloat y = x*aa;
CGFloat lastScreenShotViewHeigh = kkBackViewHeight;
[lastScreenShotView setFrame:CGRectMake(startBackViewX+y,
0,
kkBackViewWidth,
lastScreenShotViewHeigh)];
}
基本的实现都在上面了,如果想满足不同的返回动画,只需修改其中的部分代码 都能满足返回动画。
最后希望能帮助你