抽屉效果

思路:跟控制器(rootVc)添加子控制器(下面三个)的view在跟控制器的 view 上面。(注意三个子控制器的 view 添加到 rootVc 的 view 上面的顺序不同,侧滑出现抽屉的效果也不一样),给 middleVc 的 view 添加一个滑动的手势,计算手势的偏移,修改三个 view 的 frame,在middleVc 的 view 上面添加一个蒙版,添加点击事件,回到中间的 view。

主要代码:(添加子控制器的就不写了)


1.#pragma mark ------>> 给视图控制器上的  View 添加平移 手势 以及 遮挡的 MaskView 加点击手势 <<------

```

- (void)addOurGestureRecognizer

{

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panContainViewAction:)]; // 右滑动时候  出来菜单

pan.delegate = self;

[_containerVC.view addGestureRecognizer:pan];

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapHiddenMenuAction:)]; // 要是菜单在  点击 MaskView 隐藏菜单

[_middleView addGestureRecognizer:tap];

}

```

#pragma mark ------>> 滑动视图控制器的 View 的时候触发方法 <<------

- (void)panContainViewAction:(UIPanGestureRecognizer *)pan

{

// 偏移量

CGPoint offSet = [pan translationInView:_containerVC.view];

// 平移进行时候

if (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged)

{

if (offSet.x > 0)//向右滑动

{

if (self.frame.origin.x == 0)

{

return;

}

CGFloat tempX = self.frame.origin.x + offSet.x;// 算出更新的 x

if (tempX <= 0 )

{// 小于 0 就随着拖动移动就好

self.frame = CGRectMake(tempX, 0, kScreenWidth, kScreenHeight);

}else

{// 都出来之后 就让它完全展示就好  别滑到太靠右地方

self.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);

}

}else

{// 向左滑动

CGFloat tempX = self.frame.origin.x + offSet.x;// 算出更新的 x

self.frame = CGRectMake(tempX, 0, kScreenWidth, kScreenHeight);

}

}else

{// 在这里判断要 显示还是隐藏

if (self.frame.origin.x >= - MENU_WIDTH * 0.5)

{

[self inputOfSightMenuView];

}else

{

[self outOfSightMenuView];

}

}

// 清除偏移量

[pan setTranslation:(CGPointZero) inView:_containerVC.view];

//self.maskView.frame = CGRectMake(CGRectGetMaxX(self.frame), 0, kScreenWidth, kScreenHeight);

}

// 点击遮挡  收起菜单

- (void)tapHiddenMenuAction:(UITapGestureRecognizer *)tap

{

[self outOfSightMenuView];

}

#pragma mark ------>> MenuView 视图 移出 或者 移进 视线  <<------

// 放到视线之外

- (void)outOfSightMenuView

{

[UIView animateWithDuration:0.2 animations:^{

self.frame = CGRectMake(- kScreenWidth, 0, kScreenWidth, kScreenHeight);

self.isMenuViewHidden = YES;

self.maskView.hidden = YES;

}];

}

// 放到视线之内

- (void)inputOfSightMenuView

{

[UIView animateWithDuration:0.2 animations:^{

self.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);

} completion:^(BOOL finished) {

self.maskView.hidden = NO;

self.maskView.alpha = 0.6;(自己定)

}];

}

#pragma mark ------>> KVO 监控 菜单View 的位置变化 <<------

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

if ([keyPath isEqualToString:@"frame"])

{

CGRect newFrame = [change[@"new"] CGRectValue];

CGFloat newFrameX = newFrame.origin.x;

// 判断是否需要改变 遮挡的透明度

if (newFrameX != - MENU_WIDTH)

{

_maskView.hidden = NO;// 出现遮挡

// 改变遮挡的透明度

_maskView.alpha = (newFrameX + kScreenWidth) / kScreenWidth * 0.8;

}else

{

_maskView.hidden = YES;

}

}

}

#pragma mark ------>> 手势冲突时候 调用的手势代理 <<------

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

{

if ([otherGestureRecognizer.view isKindOfClass:[UITableView class]]) {

return NO;

}

return YES;

}

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一.RESideMenu 现在大多App的主框架都是UITabBarController加若干导航控制器或者是带有...
    laitys阅读 824评论 0 4
  • 1)双向抽屉视图 2)抽屉动画 3)双向抽屉视图带缩放效果 4)抽屉视图动画缩放 #import "ApDrawe...
    衹氏阅读 1,875评论 0 0
  • 目前市场上很多APP都有抽屉效果的界面,界面大同小异,一下是我个人分析和实现的抽屉效果,我是以代码加注释的方式分析...
    coderwx阅读 763评论 0 0
  • //定义属性宏 #define LWKeyPath(objc, keyPath) @(((void)objc.ke...
    年轻在于折腾阅读 1,889评论 0 3
  • #import "SSYViewController.h" #define ScreenW [UIScreen m...
    iOSkiller阅读 378评论 0 0