标签:
10-抽屉效果
第一步:搭建界面
- (void)viewDidLoad {
[super viewDidLoad];
//搭建界面
[self setUpView];
}
- (void)setUpView{
//添加左边的View
UIView *leftV = [[UIView alloc] initWithFrame:self.view.bounds];
//左边蓝
leftV.backgroundColor = [UIColor blueColor];
[self.view addSubview:leftV];
//添加右边的View
UIView *rightV = [[UIView alloc] initWithFrame:self.view.bounds];
//右边绿
rightV.backgroundColor = [UIColor greenColor];
self.rightV = rightV;
[self.view addSubview:rightV];
//添加中间的View(中间一个最后添加,显示到最外面.)
UIView *mainV = [[UIView alloc] initWithFrame:self.view.bounds];
//中间红
mainV.backgroundColor = [UIColor redColor];
self.mainV = mainV;
[self.view addSubview:mainV];
}
第二步.添加手势.能够让中间的红色View左右移动,要在控制器View加载完成时就要添加View
- (void)viewDidLoad {
[super viewDidLoad];
//搭建界面
[self setUpView];
//拖动手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
//添加手势
[self.mainV addGestureRecognizer:pan];
}
实现手势方法:
当手指拖动时调用.
-(void)pan:(UIPanGestureRecognizer *)pan{
//获取手指在屏幕上的偏移量
CGPoint transP = [pan translationInView:self.mainV];
//注意:在这里为什么不用Transform,是因为我们移动时,要改变的尺寸大小. 用Transform只能改变它的位置.
self.mainV.transform = CGAffineTransformTranslate(self.mainV.transform, transP.x, 0);
//计算mainV的Frame
//单独抽出一个方法来计算mainV的frame.因为要计算它的Y值和高度.代码会很多.所以单独抽出一个方法
self.mainV.frame = [self frameWithOffsetX:transP.x];
//每次移动时判断当前MainV的x值是大于0还是小于0.如果是大于0,就显示左边,小于0,显示右边
if (self.mainV.frame.origin.x > 0) {
self.rightV.hidden = YES;
}else if(self.mainV.frame.origin.x < 0){
self.rightV.hidden = NO;
}
//注意要做复位
[pan setTranslation:CGPointZero inView:self.mainV];
}
//最大Y值为100
#define maxY 100
//根据偏移量计算mainV的frame.
- (CGRect)frameWithOffsetX:(CGFloat)offsetX{
//取出最原始的Frame
CGRect frame = self.mainV.frame;
frame.origin.x += offsetX;
//获取屏幕的宽度
(计算Y值如下图:找最大值.当Main.x拖动最大的时候,Main.y值也最大.main.x 最大为屏幕的宽度)
设定一个最大Y值MaxY为100,正好.当max.x为屏幕的宽度时,最大Y等于100,所以Y值等于main.y = main.x * maxY / ScreenW;
100 = 375 * 100 / 375;)
有可能frame.origin.x有可能是小于0,小于0的话, 得出的Y值就会小于0,小于0就会出现, 红色的View向上 .
//对结果取绝对值.
frame.origin.y= fabs(frame.origin.x*maxY/screenW);
计算frame的高度 (当前Main的高度等于屏幕的高度减去两倍的Y值.)
frame.size.height = screenH - 2 * frame.origin.y;
//返回计算好的frame.
return frame;
}
第三步:当手指松开时做到自动定位.
MainV定位到右侧的X值
#define targetR 275
MainV定位到右侧的X值
#define targetL -275
//当手指拖动时调用.
-(void)pan:(UIPanGestureRecognizer *)pan{
//获取手指在屏幕上的偏移量
CGPoint transP = [pan translationInView:self.mainV];
//在这为什么不使用Transform,是因为我们移动时,要改变的尺寸大小. Transform只能改变它的位置.
self.mainV.transform = CGAffineTransformTranslate(self.mainV.transform, transP.x, 0);
//计算mainV的Frame
//单独抽出一个方法来计算mainV的frame.因为要计算它的Y值和高度.代码会很多.所以单独抽出一个方法
self.mainV.frame = [self frameWithOffsetX:transP.x];
//每次移动时判断当前MainV的x值是大于0还是小于0.如果是大于0 ,就显在左边,小于0 显示右边
if (self.mainV.frame.origin.x > 0) {
self.rightV.hidden = YES;
}else if(self.mainV.frame.origin.x < 0){
self.rightV.hidden = NO;
}
//判断手指的状态
if(pan.state == UIGestureRecognizerStateEnded){
//当手指松开时进入执行
记录最终判断结果后.定位的值.
CGFloat target = 0;
当手指松开,要判断MainV的x值是否大于屏幕的一半.如果大于屏幕一半时,自动定位到右边 那个位置.
if (self.mainV.frame.origin.x > screenW * 0.5) {
target = targetR;
}else if(CGRectGetMaxX(self.mainV.frame) < screenW * 0.5){
//当手指松开,要判断MainV的最大的X值是否小于屏幕的一半.如果小于屏幕的一半时, 动定位到左边的位置.
target = targetL;
}
//最终定位的x值 - 当前的main.x的值. 求出偏移量.使其定位
CGFloat offsetX = target - self.mainV.frame.origin.x;
//根据偏移量设置mainV的frame值
CGRect frame = [self frameWithOffsetX:offsetX];
[UIView animateWithDuration:0.25 animations:^{
//伴随动画设置frame
self.mainV.frame = frame; }];
}
//注意要做复位
[pan setTranslation:CGPointZero inView:self.mainV];
}
标签:
原文地址:http://www.cnblogs.com/zhoudaquan/p/5037436.html