• 分类

  • 重置

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

    实现效果:

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