iOS實現抽屜效果
抽屜效果
在iOS中很多應用都用到了抽屜效果,例如騰訊的QQ,百度貼吧…
———
1. 最終效果如下圖所示
———
2.實現步驟
1.開始啟動的時候,新建3個不同顏色的View的
1.設置3個成員屬性,記錄三種顏色的View
@property (nonatomic,weak) UIView* redView; @property (nonatomic,weak) UIView* greenView; @property (nonatomic,weak) UIView* blueView;
2.初始化3個View
- (void)setUpthreeViews
{
UIView *blueView = [[UIView alloc]initWithFrame:self.view.bounds];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];
_blueView = blueView;
UIView *greenView = [[UIView alloc]initWithFrame:self.view.bounds];
greenView.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenView];
_greenView = greenView;
UIView *redView = [[UIView alloc]initWithFrame:self.view.bounds];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
_redView = redView;
}</pre>
2.實現滑動的效果
1.通過-(void)touchesMoved:(NSSet )touches withEvent:(UIEvent )event方法來獲得當前點和初始點,從而計算出偏移量,然后計算redView的frame的值:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//獲得當前點
CGPoint currentPoint = [touch locationInView:_redView];
//獲得起點
CGPoint prePoint = [touch previousLocationInView:_redView];
//計算在x軸方向上的偏移量
CGFloat moveX = currentPoint.x - prePoint.x;
//然后通過在x軸上的偏移量,計算redView的frame
_redView.frame = [self framWithOffsetX:moveX];
}
-
假設x移到320時,y移動到60,算出每移動一點x,移動多少y
-
offsetY = offsetX * 600 / 320 手指每移動一點,x軸偏移量多少,y偏移多少
- 為了好看,x移動到320,距離上下的高度需要保持一致,而且有一定的比例去縮放他的尺寸。
- touchMove只能拿到之前的frame.當前的高度 = 之前的高度 * 這個比例
縮放比例:當前的高度/之前的高度 (screenH - 2 * offsetY) / screenH。
當前的寬度保持不變就行。
- y值,計算比較特殊,不能直接用之前的y,加上offsetY,往左滑動,主視圖應該往下走,但是offsetX是負數,導致主視圖會往上走。所以需要判斷是左滑還是右滑
- (CGRect)framWithOffsetX:(CGFloat)offsetX
{
//計算在y軸方向上的偏移量
CGFloat offsetY = offsetX/SCREENWIDTH MAXYOFFSET;
//根據y方向的偏移量計算縮放比例
CGFloat scale = (SCREENHEIGHT - 2offsetY)/SCREENHEIGHT;
//如果x < 0表示左滑
if (_redView.frame.origin.x < 0) {
scale = (SCREENHEIGHT + 2*offsetY)/SCREENHEIGHT;
}
CGRect frame = _redView.frame;
//計算滑動之后的frame
CGFloat height = frame.size.height*scale;
CGFloat width = frame.size.width;
CGFloat x = frame.origin.x + offsetX;
CGFloat y = (SCREENHEIGHT- height)* 0.5;
return CGRectMake(x, y, width, height);
}</pre>
2.通過KVO來監聽redView的frame的變化,從而判斷redView是左滑還是右滑。往左移動,顯示右邊,隱藏左邊 往右移動,顯示左邊,隱藏右邊
- (void)viewDidLoad {
[super viewDidLoad];
[self setUpthreeViews];
// 利用KVO時刻監聽_redView.frame改變
// Observer:誰需要觀察
// KeyPath:監聽的屬性名稱
// options: NSKeyValueObservingOptionNew監聽這個屬性新值
[_redView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
}
// 只要監聽的屬性有新值的時候,只要redView.frame一改變就會調用
- (void)observeValueForKeyPath:(NSString )keyPath ofObject:(id)object change:(NSDictionary )change context:(void *)context
{
if (self.redView.frame.origin.x > 0) {
} else if(self.redView.frame.origin.x < 0){_greenView.hidden = NO;
} }_greenView.hidden = YES;
// 當對象銷毀的時候,一定要移除觀察者
- (void)dealloc
{
[_redView removeObserver:self forKeyPath:@"frame"];
}</pre>
3.設置觸摸結束的時候,redView的frame。如果redView側滑沒有到屏幕的一半,則自動返回到初始位置。如果超過屏幕的一半,則停留在一個新的位置- (void)touchesEnded:(NSSet )touches withEvent:(UIEvent )event { CGFloat xPos = _redView.frame.origin.x; //大于屏幕的一半進入新的位置 if (xPos > SCREENWIDTH*0.5) {
} //小于屏幕的一半,大于屏幕負一半的時候,則恢復到初始狀態 if (xPos < SCREENWIDTH0.5 && xPos > -SCREENWIDTH0.5) {[UIView animateWithDuration:0.5 animations:^{ self.redView.frame = [self framWithBigThanX:ENDRIGHTX]; }]; return ;
} //xPos < -SCREENWIDTH*0.5的時候,進入新的位置 [UIView animateWithDuration:0.5 animations:^{[UIView animateWithDuration:0.5 animations:^{ self.redView.frame = [UIScreen mainScreen].bounds; }]; return ;
}];self.redView.frame = [self framWithSmallThanX:ENDLEFTX];
}
(CGRect)framWithBigThanX:(CGFloat)offsetX {
CGFloat offsetY = offsetX/SCREENWIDTH MAXYOFFSET; CGFloat scale = (SCREENHEIGHT - 2offsetY)/SCREENHEIGHT;
CGFloat height = SCREENHEIGHTscale; CGFloat width = SCREENWIDTH; CGFloat x = offsetX; CGFloat y = (SCREENHEIGHT- height) 0.5;
return CGRectMake(x, y, width, height); }
(CGRect)framWithSmallThanX:(CGFloat)offsetX { CGFloat offsetY = offsetX/SCREENWIDTH MAXYOFFSET; CGFloat scale = (SCREENHEIGHT + 2offsetY)/SCREENHEIGHT;
CGFloat height = SCREENHEIGHTscale; CGFloat width = SCREENWIDTH; CGFloat x = offsetX; CGFloat y = (SCREENHEIGHT- height) 0.5;
return CGRectMake(x, y, width, height); }</pre>