抽屉效果功能实现

抽屉效果功能实现

一、.h文件

@interface
HMDrawViewController :

UIViewController

@property
(nonatomic,

weak,
readonly)

UIView *mainView;

@property
(nonatomic,

weak,
readonly)

UIView *leftView;

@property
(nonatomic,

weak,
readonly)

UIView *rightView;

@end

二、.m文件

@interface

HMDrawViewController
()

@property
(nonatomic,

assign)
BOOL isDraging;

@end

@implementation
HMDrawViewController

- (void)viewDidLoad

{

// UIViewController

[super
viewDidLoad];

// Do any additional setup after loading the view.

// 1.添加子控件

[self
addChildView];

#warning
第三步
观察_mainView的frame改变

// 2.监听

/**


给_mainView添加一个观察者

*

*  KeyPath:监听frame这个属性

*

*  options:监听新值的改变

*/

[_mainView
addObserver:self
forKeyPath:@"frame"
options:NSKeyValueObservingOptionNew
context:nil];

}

//
当_mainView的frame属性改变的时候就会调用

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

{

NSLog(@"%@",
NSStringFromCGRect(_mainView.frame));

if (_mainView.frame.origin.x
<
0) {
//
往左移动

//
显示右边

_rightView.hidden
=
NO;

//
隐藏左边

_leftView.hidden
=
YES;

}else

if (_mainView.frame.origin.x
>
0){
//
往右移动

//
显示左边

_rightView.hidden
=
YES;

//
隐藏右边

_leftView.hidden
=
NO;

}

}

#warning
第一步

- (void)addChildView

{

// left

UIView *leftView = [[UIView
alloc]
initWithFrame:self.view.bounds];

leftView.backgroundColor
= [UIColor
greenColor];

[self.view
addSubview:leftView];

_leftView = leftView;

// right

UIView *rightView = [[UIView
alloc]
initWithFrame:self.view.bounds];

rightView.backgroundColor
= [UIColor
blueColor];

[self.view
addSubview:rightView];

_rightView = rightView;

// mainView

UIView *mainView = [[UIView
alloc]
initWithFrame:self.view.bounds];

mainView.backgroundColor
= [UIColor
redColor];

[self.view
addSubview:mainView];

_mainView = mainView;

}

#warning
第二步

- (void)touchesMoved:(NSSet
*)touches withEvent:(UIEvent
*)event

{

//
获取UITouch对象

UITouch *touch = [touches
anyObject];

//
获取当前点

CGPoint currentPoint = [touch
locationInView:self.view];

//
获取上一个点

CGPoint prePoint = [touch
previousLocationInView:self.view];

// x轴偏移量:当手指移动一点的时候,x偏移多少

CGFloat offsetX = currentPoint.x
- prePoint.x;

//
设置当前主视图的frame

_mainView.frame
= [self
getCurrentFrameWithOffsetX:offsetX];

_isDraging =

YES;

}

#warning
第四步

#define HMMaxY
60

//
当手指偏移一点,根据X轴的偏移量算出当前主视图的frame

- (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX

{

CGFloat screenW = [UIScreen
mainScreen].bounds.size.width;

CGFloat screenH = [UIScreen
mainScreen].bounds.size.height;

//
获取y轴偏移量,手指每移动一点,y轴偏移多少

CGFloat offsetY = offsetX *
HMMaxY
/ screenW;

CGFloat scale = (screenH -
2
* offsetY) / screenH;

if (_mainView.frame.origin.x
<
0) {
//
往左边滑动

scale = (screenH +
2 * offsetY) / screenH;

}

//
获取之前的frame

CGRect frame =

_mainView.frame;

frame.origin.x
+= offsetX;

frame.size.height
= frame.size.height
*scale;

frame.size.width
= frame.size.width
*scale;

frame.origin.y
= (screenH - frame.size.height)
*
0.5;

return frame;

}

注意:

抽屉效果的固定的高度是写死的,可以定义一个宏,方便后期的维护。

算法:

offsetY =
offsetX *
60
/
320

scale =  currentH / screenH

currentH  =  screenH –
2 * offsetY

x = frame. origin.x + offsetX

h = frame.size.height * scale

w = frame.size.weight * scale

y =( screenH – h ) *
0.5

#define HMRTarget
250

#define HMLTarget -220

/*

_mainView.frame.origin.x > screenW * 0.5
定位到右边

CGRectGetMaxX(_mainView.frame) < screenW * 0.5
定位到左边
-220

*/

//
定位

- (void)touchesEnded:(NSSet
*)touches withEvent:(UIEvent
*)event

{

//
复位

if (_isDraging
==
NO &&
_mainView.frame.origin.x
!=
0) {

[UIView
animateWithDuration:0.25
animations:^{

_mainView.frame
=
self.view.bounds;

}];

}

CGFloat screenW = [UIScreen
mainScreen].bounds.size.width;

CGFloat target =
0;

if (_mainView.frame.origin.x
> screenW *
0.5) {
//
定位到右边

target =
HMRTarget;

}else

if (CGRectGetMaxX(_mainView.frame)
< screenW *
0.5) {
//
定位到左边

target =
HMLTarget;

}

[UIView
animateWithDuration:0.25
animations:^{

if (target) {
//
在需要定位左边或者右边

//
获取x轴偏移量

CGFloat offsetX = target -

_mainView.frame.origin.x;

//
设置当前主视图的frame

_mainView.frame
= [self
getCurrentFrameWithOffsetX:offsetX];

}else{
//
还原

_mainView.frame
=
self.view.bounds;

}

}];

_isDraging =

NO;

}

注意:

复位的时候,需要定义一个成员变量记录。

@end

注意:

知识点1:KVO观察者模式,给_mainView添加一个观察者, KeyPath:监听frame这个属性,options:监听新值的改变,当frame属性的值发生改变的时候就会调用下面这个方法。

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

知识点2:抽屉效果的算法。

时间: 2024-08-24 20:36:27

抽屉效果功能实现的相关文章

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

抽屉效果的实现

抽屉效果 添加子视图 *   简单的滑动效果 * 监听控制器处理事件方法 * 获取x轴偏移量 * 改变主视图的frame *   利用KVO做视图切换 往左移动,显示右边,隐藏左边 往右移动,显示左边,隐藏右边 *  复杂的滑动效果,PPT讲解(根据手指每移动一点,x轴的偏移量算出当前视图的frame) 假设x移到320时,y移动到60,算出没移动一点x,移动多少y offsetY = offsetX * 60 / 320  手指每移动一点,x轴偏移量多少,y偏移多少 为了好看,x移动到320,

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

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

Android侧滑抽屉效果实现

1.先看效果图 2.说明 2.1目前市场上面很多软件都流行这种抽屉小果的实现,就我而言,这种设计是比较容易搭建框架的,而且UI效果也是非常不错的. 3 文章引用 3.1.Android 抽屉效果的导航菜单实现 3.2Android官方终于支持 Navigation Drawer(导航抽屉)模式 4.库的引用 4.1首先, DrawerLayout这个类是在Support Library里的,需要加上android-support-v4.jar这个包. 4.2然后程序中用时在前面导入import

Android-自定义滑动菜单(抽屉效果)

在Andoird使用Android自带的那些组件,像SlidingDrawer和DrawerLayout都是抽屉效果的菜单,但是在项目很多要实现的功能都收到Android这些自带组件的限制,导致很难完成项目的需求,自定义的组件,各方面都在自己的控制之下,从而根据需求做出调整.想要实现好的效果,基本上都的基于Android的OnTouch事件自己实现响应的功能. 首先,给大家先看一下整体的效果: 滑动的加速度效果都是有的,具体的体验,只能安装后才能查看. 接下来,看代码: 代码从MainActiv

剖析Path侧边栏抽屉效果原理(抽屉效果,Path效果)

如今很多App应用,都用到了侧边栏的效果,比如网易新闻(还带有偏移缩小),今日头条(普遍这种),Path(最先应用这种抽屉效果,所以这种效果也叫Path效果),code4App上已经有很多网友写的第三方侧边栏类,大家可以直接拿来用.这里我主要的是介绍一下这种效果的实现原理,涉及了几个知识点,在其他地方也能用到. UINavigationController和UITabBarController是2个主要的视图控制容器,都有属性viewControllers,能够很好地管理多个视图控制器.但有的时

iOS中 超简单抽屉效果(MMDrawerController)的实现

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

Android---62---DrawerLayout实现抽屉效果

如何实现android中的抽屉效果? 1.创建xml文件 其根视图是<android.support.v4.widget.DrawerLayout/> 这个xml分为两部分,一部分是主要内容的视图,一部分是抽屉的视图. 主要内容视图一般是FrameLayout,一定要是DrawerLayout的第一个视图,其高度和父视图的高度匹配. 抽屉视图一般是ListView,在写抽屉视图的时候要注意 1.宽度一般要小于320dp 2.android:layout_gravity属性是确定抽屉的位置 当该

利用DrawerLayout实现简单的抽屉效果

前言,本篇文章是最基础的利用DrawerLayout实现抽屉效果,我也是尽量精简到了最高效的代码,后面我会贴出其他比较复杂的功能. 先看效果图 标题栏中的文字,会根据点击item的不同,而显示不同的样式. 直接上代码. 下面是activity_main的代码 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.andr