ios 仿新浪微博 UINavigationController 向左滑动时显示上一个控制器的View.

仿新浪微博 UINavigationController 向左滑动时显示上一个控制器的View.

实现原理,UINavigationController 的 self.view显示时把当前显示的view截图下来,保存到一个数组中。当push一个view时把上一个view的截图放到self.view后面,当self.view向右拖动时显示上一个view。

NavigationController.m

#import "NavigationController.h"

@interface NavigationController ()
/** 存放每一个控制器的全屏截图 */
@property (nonatomic, strong) NSMutableArray *images;
@property (nonatomic, strong) UIImageView *lastVcView;
@property (nonatomic, strong) UIView *cover;
@end

@implementation NavigationController

- (UIImageView *)lastVcView
{
    if (!_lastVcView) {
        UIWindow *window = [UIApplication sharedApplication].keyWindow;
        UIImageView *lastVcView = [[UIImageView alloc] init];
        lastVcView.frame = window.bounds;
        self.lastVcView = lastVcView;
    }
    return _lastVcView;
}

- (UIView *)cover
{
    if (!_cover) {
        UIWindow *window = [UIApplication sharedApplication].keyWindow;
        UIView *cover = [[UIView alloc] init];
        cover.backgroundColor = [UIColor blackColor];
        cover.frame = window.bounds;
        cover.alpha = 0.5;
        self.cover = cover;
    }
    return _cover;
}

- (NSMutableArray *)images
{
    if (!_images) {
        self.images = [[NSMutableArray alloc] init];
    }
    return _images;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // 拖拽手势
    UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragging:)];
    [self.view addGestureRecognizer:recognizer];
}

- (void)dragging:(UIPanGestureRecognizer *)recognizer
{
    // 如果只有1个子控制器,停止拖拽
    if (self.viewControllers.count <= 1) return;

    // 在x方向上移动的距离
    CGFloat tx = [recognizer translationInView:self.view].x;
    if (tx < 0) return;

    if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) {
        // 决定pop还是还原
        CGFloat x = self.view.frame.origin.x;
        if (x >= self.view.frame.size.width * 0.5) {
            [UIView animateWithDuration:0.25 animations:^{
                self.view.transform = CGAffineTransformMakeTranslation(self.view.frame.size.width, 0);
            } completion:^(BOOL finished) {
                [self popViewControllerAnimated:NO];
                [self.lastVcView removeFromSuperview];
                [self.cover removeFromSuperview];
                self.view.transform = CGAffineTransformIdentity;
                [self.images removeLastObject];
            }];
        } else {
            [UIView animateWithDuration:0.25 animations:^{
                self.view.transform = CGAffineTransformIdentity;
            }];
        }
    } else {
        // 移动view
        self.view.transform = CGAffineTransformMakeTranslation(tx, 0);

        UIWindow *window = [UIApplication sharedApplication].keyWindow;
        // 添加截图到最后面
        self.lastVcView.image = self.images[self.images.count - 2];
        [window insertSubview:self.lastVcView atIndex:0];
        [window insertSubview:self.cover aboveSubview:self.lastVcView];
    }
}

/**
 *  产生截图
 */
- (void)createScreenShot
{
    UIGraphicsBeginImageContextWithOptions(self.view.frame.size, YES, 0.0);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    [self.images addObject:image];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if (self.images.count > 0) return;

    [self createScreenShot];
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [super pushViewController:viewController animated:animated];

    [self createScreenShot];
}

@end
时间: 2024-12-20 23:25:10

ios 仿新浪微博 UINavigationController 向左滑动时显示上一个控制器的View.的相关文章

ios开发:UINavigationController反方向滑动push

新建个UINavigationController的类别: #import "UINavigationController+CustomAnimation.h" @implementation UINavigationController (CustomAnimation) - (void)customPushViewController:(UIViewController *)viewController { viewController.view.frame = (CGRect){

Android 仿QQ浏览器WebView,滑动隐藏显示ActionBar效果

Android 仿QQ浏览器,滑动隐藏显示ActionBar效果. 往上推,是一个ScrollView会将,actionbar以及内容往上推,当actionbar消失后,将滚动Webview的内容. 此效果是基于QuickReturnHeader源码,修改而来的,代码也不多,实现方法比较简单. 直接上demo:http://download.csdn.net/detail/xufeifandj/8388493 直接看效果图:

JQ 移动端返回顶部,往下滑动时显示返回按钮,往上滑动时隐藏返回按钮

returnTop:function(){ //预定义返回顶部的html代码,它的css样式默认为不显示 var gotoTop_html = '<div class="returnTop"></div>'; //将返回顶部的html代码插入页面上id为page的元素的末尾 $(".ding_C_returnTop").append(gotoTop_html); var windowTop=0;//初始话可视区域距离页面顶端的距离 $(doc

jquery怎么在点击li标签之后添加一个在class,点击下一个li时删除上一个class?

思路:点击当前li元素后是用removeClass()删除所有兄弟元素(使用siblings()获取)的class样式,然后使用addClass()为当前li添加class. 具体演示如下: 1.HTML结构:设计三个li元素 <ul id="test"> <li>Glen</li> <li>Tane</li> <li>John</li> </ul> 2.css样式:设计一个类selecte

ios 给一个控制器的view设置背景图片

- (void)imageBg{    UIImage *oldImage = [UIImage imageNamed:@"me"];        UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0.0);    [oldImage drawInRect:self.view.bounds];    UIImage *newImage = UIGraphicsGetImageFromCurrentImag

jquery点击li标签之后在该li标签上添加一个class,点击下一个li时删除上一个li的class

思路:点击当前li元素后是用removeClass()删除所有兄弟元素(使用siblings()获取)的class样式,然后使用addClass()为当前li添加class 具体演示如下: 1.HTML结构:设计三个li元素 <ul id="test"> <li>Glen</li> <li>Tane</li> <li>John</li> </ul> 2.css样式:设计一个类selected

高仿 美团 向左滑动删除条目

1.效果图             2.功能实现 2.1 布局结构 <?xml version="1.0" encoding="UTF-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height=&quo

Android Animation动画实战(一): 从布局动画引入ListView滑动时,每一Item项的显示动画

前言: 之前,我已经写了两篇博文,给大家介绍了Android的基础动画是如何实现的,如果还不清楚的,可以点击查看:Android Animation动画详解(一): 补间动画 及 Android Animation动画详解(二): 组合动画特效 . 已经熟悉了基础动画的实现后,便可以试着去实现常见APP中出现过的那些精美的动画.今天我主要给大家引入一个APP的ListView的动画效果: 当展示ListView时,Listview的每一个列表项都按照规定的动画显示出来. 说起来比较抽象,先给大家

js移动端向左滑动出现删除按钮

最近在做移动端项目时,需要实现一个列表页面的每一项item向左滑动时出现相应的删除按钮,本来想着直接使用zepto的touch.js插件,因为之前实现相同的功能时用过这个插件,当时还挺好用的,直接使用它的swipeLeft和swipeRight方法即可,可是今天又开始做这个功能时,却发现这两个方法在使用时毫无效果,一点反应都没有.上网查资料,又下载了最新版本的zepto和touch.js,都没有用,也不知为什么?所以就弃用了这个插件.下面是我后来实现后的代码,其实就是用了原生js的touch事件