您好,登錄后才能下訂單哦!
一、.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:抽屜效果的算法。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。