【问题标题】:pan-/slideable view like camera lock screen平移/滑动视图,如相机锁定屏幕
【发布时间】:2012-07-02 22:01:45
【问题描述】:

每个人都知道相机锁屏中的可拖动视图

我想要类似的东西。我的布局是这样的

  • 这个子视图应该可以从底部拖动并且应该保持打开状态 在某个高度。
  • 当快速向上滑动时,它应该会自行打开 当向上拖动子视图但在最大位置之前停止时,它 应该先滑下去再滑下去
  • 它也会自己倒下的
  • 点击时应自行向上/向下滑动

您可以在锁定屏幕上看到这种行为非常好(高度停止除外)。 我尝试了不同的东西,比如UIPanGestureRecognizer,然后设置了一个最大值,但是我无法滑动。

UIKit 中是否有一些预先打包的东西,或者让我自己做。如果不是,对于这种行为有什么好的方法?

【问题讨论】:

  • 您好!这正是我正在寻找的。你找到实现这种行为的方法了吗?
  • @DmitryZhukov 不抱歉。还没有找到任何东西。如果你能找到什么,请告诉我!

标签: objective-c ios animation uiview uigesturerecognizer


【解决方案1】:

计划如下:您将继承 UIView。您将添加一些属性并覆盖一些方法。这个想法是让手指通过 touchesBegan 和 touchesMoved 来决定运动。当手指在 touchesEnded 中抬起时,您可以将视图设置为合适的静止位置。在我提供的代码示例中,这将完全展开或完全缩回,但如果您愿意,您可以随时将其缩回。

听起来你想要应用一点惯性。这稍微复杂一些,因为您必须自己添加一个额外的动画 - 但同样,您只需要插入正确的动画(例如,使用计时功能让它动画超过终点然后重新插入)并拥有它在用户完成移动后触发。如果您想变得花哨,您可以跟踪滑动的速度并根据此速度/动量触发动画。

以下是一个代码示例,可帮助为抽屉设置动画效果。它没有你所描述的那种幻想,但它应该为你提供一个基础,让你弄清楚如何以及在哪里引入这种行为。

你的类需要一些属性/变量:一个“当前点”、一个原点、一个天花板(视图应该停止向上拖动的点,或者它停留在“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];

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多