抽屜效果功能實現,抽屜效果實現
抽屜效果功能實現一、.h檔案@interfaceHMDrawViewController :UIViewController
@property(nonatomic,weak, readonly)UIView *mainView;
@property(nonatomic,weak, readonly)UIView *leftView;
@property(nonatomic,weak, readonly)UIView *rightView;
@end
二、.m檔案@interfaceHMDrawViewController ()
@property(nonatomic,assign) BOOL isDraging;
@end
@implementationHMDrawViewController
- (void)viewDidLoad
{
// UIViewController
[superviewDidLoad];
// Do any additional setup after loading the view.
// 1.添加子控制項
[selfaddChildView];
#warning第三步觀察_mainView的frame改變
// 2.監聽
/**
* 給_mainView添加一個觀察者
*
* KeyPath:監聽frame這個屬性
*
* options:監聽新值的改變
*/
[_mainViewaddObserver:selfforKeyPath:@"frame"options:NSKeyValueObservingOptionNewcontext: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;
}elseif (_mainView.frame.origin.x> 0){ // 往右移動
// 顯示左邊
_rightView.hidden= YES;
// 隱藏右邊
_leftView.hidden= NO;
}
}
#warning第一步
- (void)addChildView
{
// left
UIView *leftView = [[UIViewalloc]initWithFrame:self.view.bounds];
leftView.backgroundColor= [UIColorgreenColor];
[self.viewaddSubview:leftView];
_leftView = leftView;
// right
UIView *rightView = [[UIViewalloc]initWithFrame:self.view.bounds];
rightView.backgroundColor= [UIColorblueColor];
[self.viewaddSubview:rightView];
_rightView = rightView;
// mainView
UIView *mainView = [[UIViewalloc]initWithFrame:self.view.bounds];
mainView.backgroundColor= [UIColorredColor];
[self.viewaddSubview:mainView];
_mainView = mainView;
}
#warning第二步
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
// 擷取UITouch對象
UITouch *touch = [touchesanyObject];
// 擷取當前點
CGPoint currentPoint = [touchlocationInView:self.view];
// 擷取上一個點
CGPoint prePoint = [touchpreviousLocationInView:self.view];
// x軸位移量:當手指移動一點的時候,x位移多少
CGFloat offsetX = currentPoint.x- prePoint.x;
// 設定當前主視圖的frame
_mainView.frame= [selfgetCurrentFrameWithOffsetX:offsetX];
_isDraging =YES;
}
#warning第四步
#define HMMaxY 60
//當手指位移一點,根據X軸的位移量算出當前主視圖的frame
- (CGRect)getCurrentFrameWithOffsetX:(CGFloat)offsetX
{
CGFloat screenW = [UIScreenmainScreen].bounds.size.width;
CGFloat screenH = [UIScreenmainScreen].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 HMRTarget250
#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) {
[UIViewanimateWithDuration:0.25animations:^{
_mainView.frame= self.view.bounds;
}];
}
CGFloat screenW = [UIScreenmainScreen].bounds.size.width;
CGFloat target =0;
if (_mainView.frame.origin.x> screenW * 0.5) { // 定位到右邊
target = HMRTarget;
}elseif (CGRectGetMaxX(_mainView.frame) < screenW * 0.5) { // 定位到左邊
target = HMLTarget;
}
[UIViewanimateWithDuration:0.25animations:^{
if (target) {//在需要定位左邊或者右邊
// 擷取x軸位移量
CGFloat offsetX = target -_mainView.frame.origin.x;
// 設定當前主視圖的frame
_mainView.frame= [selfgetCurrentFrameWithOffsetX: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:抽屜效果的演算法。