iOS实现简单抽屉效果

抽屉效果

所谓抽屉效果就是三个视图,向右拖拽显示左边的视图,向左拖拽显示右边的视图,当拖拽大于屏幕的一半时最上面的视图会自动定位到一边,当点击左边或右边视图时会最上面视图会自动复位。

效果如图:三个视图(左边:浅灰色视图、右边:品红视图、主视图:黑色视图)

封装代码

DrawerViewController

#import <UIKit/UIKit.h>
@interface DrawerViewController : UIViewController

@property (weak, nonatomic, readonly) UIView *leftView;
@property (weak, nonatomic, readonly) UIView *rightView;
@property (weak, nonatomic, readonly) UIView *mainView;

@end

// -------------------------------------------------------
#import "DrawerViewController.h"

#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
#define MaxOffsetY 100
#define MaxOffsetX ([UIScreen mainScreen].bounds.size.width - 100)

@implementation DrawerViewController
- (void)viewDidLoad {
  [super viewDidLoad];

  // 1. 初始化视图
  [self setup];

  // 2. 给mainView添加拖动手势
  UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
  [self.mainView addGestureRecognizer:panGestureRecognizer];

  // 3. 给self.view添加一个单击手势
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
  [self.view addGestureRecognizer:tap];
}

- (void)tapGesture:(UITapGestureRecognizer *)tap {
  // mainView复位
  [UIView animateWithDuration:0.2 animations:^{
    self.mainView.frame = self.view.bounds;
  }];
}

- (void)panGesture:(UIPanGestureRecognizer *)pan {
  CGPoint offsetPoint = [pan translationInView:self.view];
  self.mainView.frame = [self frameWithOffset:offsetPoint.x];

  if (self.mainView.frame.origin.x > 0) {
    // → 右移(显示leftView)
    self.rightView.hidden = YES;
  } else if (self.mainView.frame.origin.x < 0) {
    // ← 左移(显示rightView)
    self.rightView.hidden = NO;
  }

  // 如果拖拽结束,自动定位
  CGFloat targetOffsetX = 0;
  if (pan.state == UIGestureRecognizerStateEnded) {
    if (self.mainView.frame.origin.x >= ScreenWidth * 0.5) { // 右侧
      targetOffsetX = MaxOffsetX;
    } else if (CGRectGetMaxX(self.mainView.frame) < ScreenWidth * 0.5){ // 左侧
      targetOffsetX = -MaxOffsetX;
    }

    // 计算出当前位置距离目标位置所需要的偏移距离
    CGFloat offsetX = targetOffsetX - self.mainView.frame.origin.x;

    // 滑动不到屏幕一般时仍然显示mainView(self.view.bounds) 否则自动定位到左侧或右侧
    CGRect mainFrame = targetOffsetX == 0 ? self.view.bounds : [self frameWithOffset:offsetX];
    [UIView animateWithDuration:0.2 animations:^{
      self.mainView.frame = mainFrame;
    }];
  }

  [pan setTranslation:CGPointZero inView:self.view];
}

- (CGRect)frameWithOffset:(CGFloat)offsetX {
  CGRect newFrame = self.mainView.frame;
  newFrame.origin.x += offsetX;   // x

  CGFloat offsetY = self.mainView.frame.origin.x * MaxOffsetY / ScreenWidth;
  newFrame.origin.y = fabs(offsetY);  // y

  CGFloat offsetHeight = ScreenHeight - (newFrame.origin.y * 2);
  newFrame.size.height = offsetHeight;  // height

  return newFrame;
}

- (void)setup {
  UIView *leftView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
  //leftView.backgroundColor = [UIColor lightGrayColor];
  _leftView = leftView;
  [self.view addSubview:leftView];

  UIView *rightView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
  //rightView.backgroundColor = [UIColor magentaColor];
  _rightView = rightView;
  [self.view addSubview:rightView];

  UIView *mainView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
  //mainView.backgroundColor = [UIColor blackColor];
  _mainView = mainView;
  [self.view addSubview:mainView];
}

@end

使用封装

1.将DrawerViewController类拖入到工程中,并继承该类
2.分别创建LeftViewController、RightViewController、MainViewController
3.将每个视图对应的view添加到对应的视图上,并成为当前控制器的子控制器

第一步:继承DrawerViewController

#import <UIKit/UIKit.h>
#import "DrawerViewController.h"
@interface ViewController : DrawerViewController

@end

第二步:分别创建LeftViewController、RightViewController、MainViewController
第三步:为leftView、rightView、mainView 添加子视图,并将每天控制器作为当前控制器的子控制器

#import "ViewController.h"
#import "LeftViewController.h"
#import "RightViewController.h"
#import "MainViewController.h"

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  // Main
  MainViewController *mainViewController = [[MainViewController alloc] init];
  mainViewController.view.frame = self.view.bounds;
  mainViewController.view.backgroundColor = [UIColor brownColor];
  [self.mainView addSubview:mainViewController.view];
  [self addChildViewController:mainViewController];

  // Left
  LeftViewController *leftViewController = [[LeftViewController alloc] init];
  leftViewController.view.frame = self.view.bounds;
  leftViewController.view.backgroundColor = [UIColor purpleColor];
  [self.leftView addSubview:leftViewController.view];
  [self addChildViewController:leftViewController];

  // Right
  RightViewController *rightViewController = [[RightViewController alloc] init];
  rightViewController.view.frame = self.view.bounds;
  rightViewController.view.backgroundColor = [UIColor cyanColor];
  [self.rightView addSubview:rightViewController.view];
  [self addChildViewController:rightViewController];
}
@end

实现效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • IOS实现点击滑动抽屉效果

    最近,看到好多Android上的抽屉效果,也忍不住想要自己写一个.在Android里面可以用SlidingDrawer,很方便的实现.IOS上面就只有自己写了.其实原理很简单就是 UIView 的移动,和一些手势的操作. 效果图: // // DrawerView.h // DrawerDemo // // Created by Zhouhaifeng on 12-3-27. // Copyright (c) 2012年 CJLU. All rights reserved. // #import

  • iOS动画之向右拉的抽屉3D效果

    首先我们忽略掉3D效果,先要做的是一个右拉的抽屉效果. 总体思路: 1.创建一个ContainerViewController容器控制器,然后把左侧选择菜单的SideMenuViewController,和右侧负责显示内容的MainViewController 添加到ContainerViewController中. 2.给容器控制器ContainerViewController添加一个手势监听,通过修改偏移量完成抽屉效果. 3.设置anchorPoint,给左侧SideMenuViewCont

  • iOS实现侧拉栏抽屉效果

    本文实例介绍了iOS实现侧拉栏抽屉效果的相关代码,分享给大家供大家参考,具体内容如下 需要导入第三方的类库如下: 抽屉效果所需第三方类库下载 效果:既可以两侧都实现抽屉效果也可只实现左侧栏或者右侧栏的抽屉效果 关于抽屉效果主要是AppDelegate的代码 AppDelegate.h文件代码: <span style="font-size:18px;"><span style="font-size:18px;">#import <UIK

  • iOS开发之路--仿网易抽屉效果

    最终效果图: MainStoryBoard示意图: BeyondViewController.h // // BeyondViewController.h // 19_抽屉效果_仿网易 // // Created by beyond on 14-8-1. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import <UIKit/UIKit.h> #import "LeftTableViewControllerD

  • iOS实现抽屉效果

    本文实例为大家分享了iOS实现抽屉效果的具体代码,供大家参考,具体内容如下 抽屉效果: #import "DragerViewController.h" #define screenW [UIScreen mainScreen].bounds.size.width @interface DragerViewController () @property (nonatomic, weak) UIView *leftV; @property (nonatomic, weak) UIView

  • ios仿侧边抽屉效果实现代码

    效果图如下 代码实现以及思路下面分析: 代码创建导航控制器 Appdelegate.m中 #import "AppDelegate.h" #import "ViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

  • iOS实现简易抽屉效果、双边抽屉效果

    本文实例为大家分享了iOS实现抽屉效果的全部代码,供大家参考,具体内容如下 iOS实现简易抽屉效果,代码: @interface ViewController () { UIView* _leftView; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from

  • iOS实现简单的抽屉效果

    说到抽屉效果在iOS中比较有名的第三方类库就是PPRevealSideViewController.一说到第三方类库就自然而然的想到我们的CocoaPods,本文用CocoaPods引入PPRevealSideViewController,然后在我们的工程中以代码结合storyboard来做出抽屉效果. 一.在工程中用CocoaPods引入第三方插件PPRevealSideViewController. (1).在终端中搜索PPRevealSideViewController的版本 (2).在P

  • iOS抽屉效果开发案例分享

    本文实例为大家分享了iOS抽屉效果开发实例,供大家参考,具体内容如下 在显示在窗口的控制器上添加三个view(如果只需要往一边滑动就只加2个view) 先声明三个view #import "ViewController.h" @interface ViewController () @property(nonatomic, weak) UIView *mainV; @property(nonatomic, weak) UIView *leftV; @property(nonatomic

  • iOS实现左右拖动抽屉效果

    本文实例介绍了iOS实现左右拖动抽屉效果,具体内容如下 利用了触摸事件滑动 touchesMoved: 来触发左右视图的出现和消失 利用loadView方法中添加view 在self.view载入前就把 左右中View都设置好frame 每一个方法都由单独的功能. #import "DarwViewController.h" @interface DarwViewController () @property (nonatomic, weak) UIView *leftView; @p

随机推荐