每个人都知道相机锁屏中的可拖动视图
我想要类似的东西。我的布局看起来像这样
你可以在锁定屏幕上看到这种行为非常好(高度停止除外)。
我尝试了UIPanGestureRecognizer
之类的不同内容,然后设置了最大值但是我无法滑动。
是否在UIKit预先包装了一些东西,或者让我自己做。如果没有,对这种行为会有什么好处?
答案 0 :(得分:6)
这是计划:你将继承UIView的子类。您将添加一些属性并覆盖一些方法。这个想法是你让手指用touchesBegan和touchesMoved来决定运动。当手指抬起触摸时,您可以将视图设置为合适的静止位置。在我提供的代码示例中,这将是完全扩展或完全缩回,但如果您愿意,可以随时撤回。
听起来你想要一点惯性。这稍微复杂一点,因为你必须自己添加一个额外的动画 - 但是,你只需要插入正确的动画(例如,让它通过结束点动画,然后使用计时功能返回)并且在用户完成移动后它会激活。如果你想要花哨,你可以跟踪滑动的速度并根据这个速度/动量来发射动画。
以下是一个代码示例,可帮助抽屉进出动画。它没有你所描述的那种幻想,但它应该为你提供一个基础来弄清楚如何以及在何处引入这种行为。
你的班级需要一些属性/ ivars:一个“当前点”,一个原点,一个天花板(视图应该停止向上拖动,或者它在“out”中停留的位置)和一个楼层(最大y偏移量,或者它不会低于下面的坐标。)
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint startPt = [touch locationInView:self];
self.currentPoint = startPt;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint activePoint = [[touches anyObject] locationInView:self];
//new position
CGPoint newPoint = CGPointMake(self.center.x,
self.center.y + (activePoint.y - currentPoint.y));
if (newPoint.y > self.draggingFloor) {
//too low
newPoint.y = self.draggingFloor;
} else if (newPoint.y < self.draggingCeiling) {
//too high
newPoint.y = self.draggingCeiling;
}
self.center = newPoint;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//The user isn't touching. Now we can adjust to drawer to a "better" position.
//The 150f here is going to depend on how far the view should be dragged before it opens.
CGFloat median = pullDrawerYOrigin + 150.0f;
CGFloat position = self.center.y;
if (position <= median) {
//We're closer to open than closed. So open all the way.
[self animateDrawerToPositionYesForOpen:YES];
}
else if (position >= median) {
//close
[self animateDrawerToPositionYesForOpen:NO];
}
}
- (CGFloat) draggingFloor {
//Don't drag any lower than this.
if (!__draggingFloor) {
__draggingFloor = pullDrawerYOrigin + (self.bounds.size.height *.5);
}
return __draggingFloor;
}
- (CGFloat) draggingCeiling {
//Don't drag any higher than this.
if (!__draggingCeiling) {
__draggingCeiling = self.superview.bounds.size.height + (self.bounds.size.height * .05);
}
return __draggingCeiling;
}
- (void) animateDrawerToPositionYesForOpen:(BOOL)position {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:.2];
CGPoint myCenter = self.center;
if (position == YES) {
myCenter.y = self.draggingCeiling;
}
else if (position == NO) {
myCenter.y = self.draggingFloor;
}
self.center = myCenter;
[UIView commitAnimations];
}