iOS实现左右拖动抽屉效果
本文实例介绍了iOS实现左右拖动抽屉效果,具体内容如下
利用了触摸事件滑动touchesMoved:来触发左右视图的出现和消失利用loadView方法中添加view在self.view载入前就把左右中View都设置好frame每一个方法都由单独的功能。
#import"DarwViewController.h"
@interfaceDarwViewController()
@property(nonatomic,weak)UIView*leftView;
@property(nonatomic,weak)UIView*rightView;
@property(nonatomic,weak)UIView*mainView;
/**
*动画是否进行
*/
@property(nonatomic,assign)BOOLanimating;
@end
@implementationDarwViewController
-(void)viewDidLoad{
[superviewDidLoad];
}
-(void)loadView
{
self.view=[[UIViewalloc]initWithFrame:[UIScreenmainScreen].bounds];
//左边view
UIView*leftView=[[UIViewalloc]initWithFrame:self.view.frame];
[self.viewaddSubview:leftView];
leftView.backgroundColor=[UIColorredColor];
self.leftView=leftView;
//右边View
UIView*rightView=[[UIViewalloc]initWithFrame:self.view.frame];
[self.viewaddSubview:rightView];
rightView.backgroundColor=[UIColorblueColor];
self.rightView=rightView;
//主页面
UIView*mainView=[[UIViewalloc]initWithFrame:self.view.frame];
[self.viewaddSubview:mainView];
mainView.backgroundColor=[UIColoryellowColor];
self.mainView=mainView;
//KVO监听
[self.mainViewaddObserver:selfforKeyPath:@"frame"options:NSKeyValueObservingOptionNewcontext:nil];
}
/**
*KVO回调方法当mainViewFrame值改变时触发
*
*@paramkeyPath<#keyPathdescription#>
*@paramobject<#objectdescription#>
*@paramchange<#changedescription#>
*@paramcontext<#contextdescription#>
*/
-(void)observeValueForKeyPath:(NSString*)keyPathofObject:(id)objectchange:(NSDictionary<NSString*,id>*)changecontext:(void*)context
{
if(self.animating)return;//如果mainView正在动画就不执行
if(self.mainView.frame.origin.x>0)
{
//X>0就隐藏右边View显示左边View
self.rightView.hidden=YES;
self.leftView.hidden=NO;
}
elseif(self.mainView.frame.origin.x<0)
{
//X<0就隐藏左边View显示右边VIew
self.leftView.hidden=YES;
self.rightView.hidden=NO;
}
}
#pragmamark--触摸事件
-(void)touchesMoved:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event
{
//获得触摸对象
UITouch*touch=[touchesanyObject];
//获得当前触摸点
CGPointcurrentPoint=[touchlocationInView:self.view];
//获得上一个触摸点
CGPointpreviousPoint=[touchpreviousLocationInView:self.view];
//计算x方向的偏移量
CGFloatoffsetX=currentPoint.x-previousPoint.x;
//根据x的偏移量计算y的偏移量
self.mainView.frame=[selfrectWithOffsetX:offsetX];
}
#definescreenW[UIScreenmainScreen].bounds.size.width
#definescreenH[UIScreenmainScreen].bounds.size.height
/**
*计算主视图的frame
*
*@paramoffsetXx的偏移量
*
*@return偏移后新的frame
*/
-(CGRect)rectWithOffsetX:(CGFloat)offsetX
{
//Y轴的偏移量
CGFloatoffsetY=(screenH*1/5)*(offsetX/screenW);
//比例:(用于宽高的缩放)
CGFloatscale=(screenH-offsetY*2)/screenH;
if(self.mainView.frame.origin.x<0)
{
//如果x是负数及左边View要显示
//比例就要设为比1小
scale=2-scale;
}
//获取当前mainView的frame
CGRectframe=self.mainView.frame;
//重新设置mainView的frame值
frame.size.width=frame.size.width*scale>screenW?screenW:frame.size.width*scale;
frame.size.height=frame.size.height*scale>screenH?screenH:frame.size.height*scale;
frame.origin.x+=offsetX;
frame.origin.y=(screenH-frame.size.height)*0.5;
//返回偏移后新的frame
returnframe;
}
#definemaxRightX(screenW*0.8)
#definemaxLeftX(-screenW*0.6)
-(void)touchesEnded:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event
{
CGFloattargetX=0;
//如果松手的那一下当前mainVIew的x大于屏幕的一半
if(self.mainView.frame.origin.x>screenW*0.5)
{
//向右边定位
targetX=maxRightX;
}
//如果松手的那一下当前mainVIew的最大X值小于屏幕的一半
elseif(CGRectGetMaxX(self.mainView.frame)<screenW*0.5)
{
//向左边定位
targetX=maxLeftX;
}
//计算偏移量
CGFloatoffsetX=targetX-self.mainView.frame.origin.x;
self.animating=YES;
[UIViewanimateWithDuration:0.4animations:^{
if(targetX==0)
{
//如果targetX==0复位
self.mainView.frame=self.view.frame;
}
else
{
//如果targetX!=0那就到指定位置
self.mainView.frame=[selfrectWithOffsetX:offsetX];
}
}completion:^(BOOLfinished){
self.animating=NO;
}];
}
@end
以上就是本文的全部内容,希望对大家的学习有所帮助。