IOS 抽屉效果

原创Blog,转载请注明出处

blog.csdn.net/hello_hwc

先看看Demo效果

视频链接如下

http://v.youku.com/v_show/id_XODc1OTQwODQ0.html

实现过程如下

1 新建一个基于单视图的工程。拖入两个ViewController,为了区分,在大纲中改为firstViewController 和 SecondViewController。沿着图中红线control+拖拽,在弹出的窗口中选择Show

2 选择Segue,为其添加Identifier为:PushSegue

3 为了区分,分别为两个ViewController设置不同的backgroundColor

4 拖入一个ImageView到FirstViewController中,然后接下来的几幅图时为ImageView设置AutoLayout

设置居中

保证长宽不变

然后,update Frame让ImageView在正确的位置,然后为ImageView选择图片

5 然后拖入一个Object到NavigationController中

6 创建一个Cocoa Class文件,继承自NSObject,命名为NavigationControllerDelegate,让其遵循UINavigationControllerDelegate

@interface NavigationControllerDelegate : NSObject<UINavigationControllerDelegate>

7让storyboard上的NavigationController的代理设置为拖入的对象,方式:大纲中右键NavigationController,然后把代理拖拽到Object上

8 然后为NavigationController设置一个Outlet

9 接下来就是代码的过程了,完整的代码如下

NavigationControllerDelegate.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface NavigationControllerDelegate : NSObject<UINavigationControllerDelegate>

@end

NavigationControllerDelegate.m

#import "NavigationControllerDelegate.h"
#import "Animator.h"

@interface NavigationControllerDelegate()<UIGestureRecognizerDelegate>

@property (strong,nonatomic)UIPercentDrivenInteractiveTransition * interactivcTransition;
@property (weak, nonatomic) IBOutlet UINavigationController *nav;
@property (strong,nonatomic) UIPanGestureRecognizer * pangesture;
@end

@implementation NavigationControllerDelegate
//添加手势
-(void)awakeFromNib{
    self.pangesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(paned:)];
    [self.nav.view addGestureRecognizer:self.pangesture];
}
//响应手势
- (void)paned:(UIPanGestureRecognizer *)sender {
    if (self.nav == nil){
        return;
    }
    CGPoint translation;
    switch (sender.state) {
        case UIGestureRecognizerStateBegan:
        {
            _interactivcTransition = [[UIPercentDrivenInteractiveTransition alloc] init];
            if (self.nav.viewControllers.count > 1) {
                [self.nav popViewControllerAnimated:YES];
            }
            else{
                [self.nav.topViewController performSegueWithIdentifier:@"PushSegue" sender:nil];
            }
        }
            break;
        case UIGestureRecognizerStateChanged:
            translation = [sender translationInView:self.nav.view];
            if (self.nav.viewControllers.count > 1 && translation.x > 0) {
                CGFloat completionProgress = translation.x/CGRectGetWidth(self.nav.view.frame);
                [self.interactivcTransition updateInteractiveTransition:completionProgress];
            }
            if (self.nav.viewControllers.count == 1 && translation.x < 0) {
                CGFloat completionProgress = -translation.x/CGRectGetWidth(self.nav.view.frame);
                [self.interactivcTransition updateInteractiveTransition:completionProgress];
            }
            break;
        case UIGestureRecognizerStateEnded:
            if (self.nav.viewControllers.count >1 && [sender velocityInView:self.nav.view].x>0) {
                [self.interactivcTransition finishInteractiveTransition];

            }else if(self.nav.viewControllers.count <= 1 && [sender velocityInView:self.nav.view].x<0){
                [self.interactivcTransition finishInteractiveTransition];
            }else{
                [self.interactivcTransition cancelInteractiveTransition];
            }
            break;
        case UIGestureRecognizerStateCancelled:
            [self.interactivcTransition cancelInteractiveTransition];
            break;
        default:
            [self.interactivcTransition cancelInteractiveTransition];
            self.interactivcTransition = nil;
            break;
    }
}
//NavigationController代理-决定了动画交互过程由哪个对象控制
- (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                          interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController{
    return self.interactivcTransition;

}
//NavigationController代理-决定了如何呈现动画
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                 animationControllerForOperation:(UINavigationControllerOperation)operation
                                              fromViewController:(UIViewController *)fromVC
                                                toViewController:(UIViewController *)toVC
{
    return [[Animator alloc] init];
}

@end

//  Animator.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface Animator : NSObject <UIViewControllerAnimatedTransitioning>

@end

//  Animator.m

//
//  Animator.m
//  HwcFoundationExample
//
//  Created by huangwenchen on 15/1/20.
//  Copyright (c) 2015年 huangwenchen. All rights reserved.
//

#import "Animator.h"

@implementation Animator
//动画时间
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.8;
}
//动画的过程
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController* fromviewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UINavigationController * nav = toViewController.navigationController;
    CGRect originFrame = toViewController.view.frame;
    CGRect offSetFrame = CGRectOffset(originFrame,-CGRectGetWidth(originFrame), 0);
    if (nav.viewControllers.count > 1) {
        [[transitionContext containerView] addSubview:toViewController.view];
        toViewController.view.frame = offSetFrame;
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            toViewController.view.frame = originFrame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
        }];

    }else
    {
        [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromviewController.view];
        fromviewController.view.frame = originFrame;
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            fromviewController.view.frame = offSetFrame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:![transitionContext transitionWasCancelled]];

        }];

    }
}
@end

第二部分

原理:这里我把抽屉的过程理解为两个ViewController的切换动画。那么,切换动画的组成要素有以下几部分

(1)动画控制器 (Animation Controllers) 遵从 UIViewControllerAnimatedTransitioning 协议,并且负责实际执行动画。

(2)交互控制器 (Interaction Controllers) 通过遵从 UIViewControllerInteractiveTransitioning 协议来控制可交互式的转场。

(3)转场代理 (Transitioning Delegates) 根据不同的转场类型方便的提供需要的动画控制器和交互控制器。

(4)转场上下文 (Transitioning Contexts) 定义了转场时需要的元数据,比如在转场过程中所参与的视图控制器和视图的相关属性。 转场上下文对象遵从 UIViewControllerContextTransitioning 协议,并且这是由系统负责生成和提供的。

(5)转场协调器(Transition Coordinators) 可以在运行转场动画时,并行的运行其他动画。 转场协调器遵从 UIViewControllerTransitionCoordinator 协议。

采用UINavigationController的话,我们只需要考虑动画控制器和交互控制器就可以了。

动画交互器由UIPercentDrivenInteractiveTransition提供

动画控制器由自定义一个类Animator,遵循UIViewControllerAnimatedTransitioning来提供,这个协议有两个必须实现的函数,就是代码中的两个函数。

这么做的好处就是动画本身的过程和ViewController解耦

BTY:demo仍然有些不完善的地方,等有时间了我再优化下

时间: 2024-10-07 08:02:41

IOS 抽屉效果的相关文章

iOS抽屉效果和侧边菜单

iOS抽屉效果和侧边菜单 源码下载地址 1.效果演示 1. 抽屉效果演示 1. 侧边菜单演示 2.使用说明 构造方法 initialization /// 构造方法(左控制器 & 右控制器 & 背景图片) -(instancetype)initWithLeftController:(UIViewController *)leftController andMainController:(UIViewController *)mainController andRightController

IOS抽屉效果功能实现

抽屉效果功能实现 一..h文件 @interface HMDrawViewController : UIViewController @property (nonatomic, weak, readonly) UIView *mainView;@property (nonatomic, weak, readonly) UIView *leftView;@property (nonatomic, weak, readonly) UIView *rightView; @end 二..m文件 @int

iOS抽屉效果

源码下载 抽屉效果第三方类库下载 所需第三方类库下载 侧拉栏抽屉效果图         需要导入的头文件: #import "MMDrawerController.h" #import "MMExampleDrawerVisualStateManager.h" 代码实现: 首先需要创建三个试图控制器 //主视图 FirstViewController *firstVC = [[FirstViewController alloc] init]; //左边视图 Seco

猫猫学IOS(二十六)UI之iOS抽屉效果小Demo

猫猫分享,必须精品 素材代码地址:http://blog.csdn.net/u013357243/article/details/45305785 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 先看效果 实现过程 第一步,把三个view设置好,还有颜色 #warning 第一步 - (void)addChildView { // left UIView *leftView = [[UIVie

(素材源码)猫猫学IOS(二十六)UI之iOS抽屉效果小Demo

猫猫分享,必须精品 素材代码地址:http://download.csdn.net/detail/u013357243/8635679 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 先看效果 源码 NYDrawViewController.h // // NYDrawViewController.h // 06-抽屉效果 // // Created by apple on 14-9-1. /

简单的iOS抽屉效果

#define screenW [UIScreen mainScreen].bounds.size.width #import "ViewController.h" @interface ViewController () @property (nonatomic,strong)UIView * redView; @property (nonatomic,strong)UIView *yellowView; @property (nonatomic,strong)UIView *gre

抽屉效果学习

1, Ios左右菜单PPRevealSideviewController使用的一些心得 代码编写 http://blog.csdn.net/qjlhlh/article/details/8204563 2 stoaryBoard编写 iOS抽屉效果的demo http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246071a27a2b820260d57938327

iOS实现抽屉效果

抽屉效果 在iOS中很多应用都用到了抽屉效果,例如腾讯的QQ,百度贴吧- --- 1. 最终效果如下图所示 --- 2.实现步骤 1.开始启动的时候,新建3个不同颜色的View的 1.设置3个成员属性,记录三种颜色的View @property (nonatomic,weak) UIView* redView; @property (nonatomic,weak) UIView* greenView; @property (nonatomic,weak) UIView* blueView; 2.

ios开发中超简单抽屉效果(MMDrawerController)的实现

ios开发中,展示类应用通常要用到抽屉效果,由于项目需要,本人找到一个demo,缩减掉一些不常用的功能,整理出一个较短的实例. 首先需要给工程添加第三方类库 MMDrawerController: 这里讲的实例只加入了左滑抽屉.右滑和左滑只是初始化时多添加一个右视图控制器,其他方法基本相同. 下面是用手势实现抽屉的拉出和收回 1.初始化跟视图控制器时,在AppDelegate中导入头文件 #import "MMDrawerController.h" 2.初始化方法先初始化左视图和中心视