【问题标题】:UIPanGestureRecognizer to maximize and minimize a UIViewUIPanGestureRecognizer 最大化和最小化 UIView
【发布时间】:2012-12-25 16:32:00
【问题描述】:

为了最小化和最大化 UIView,我使用了 UIPangestureRecognizer。代码如下:

-(void) pannningMyView:(UIPanGestureRecognizer*) panGesture{
    CGPoint newPoint=[panGesture translationInView:self.view];
    CGPoint oldPoint=self.myPanningView.frame.origin;
    CGFloat dx=newPoint.x;
    CGFloat dy=newPoint.y;
    if(dx>0){
        CGRect oldRect=self.myPanningView.frame;
        oldRect.size.width+=dx;
        oldRect.size.height+=dy;
        self.myPanningView.frame=oldRect;
    }
}

但是,过渡非常快,以至于我移动了几个像素,它覆盖了整个屏幕。我无法弄清楚我的代码需要进行哪些更正。

【问题讨论】:

    标签: ios uiview uipangesturerecognizer


    【解决方案1】:

    问题在于您的翻译是累积的,因为translationInView 是从连续手势的开头开始的,但是您正在将翻译添加到当前帧,而不是原始帧。这可以通过检查手势状态来解决,如果您处于手势的开始,则保存原始帧,然后在手势进行时将其用作未来翻译的基础。

    -(void) panningMyView:(UIPanGestureRecognizer*) panGesture
    {
        static CGRect originalFrame; // or you could make this a non-static class ivar
    
        if (panGesture.state == UIGestureRecognizerStateBegan)
        {
            originalFrame = self.myPanningView.frame;
        }
        else if (panGesture.state == UIGestureRecognizerStateChanged)
        {
            CGPoint translation = [panGesture translationInView:self.view];
            if (translation.x > 0) {
                CGRect newFrame = originalFrame;
                newFrame.size.width += translation.x;
                newFrame.size.height += translation.y;
                self.myPanningView.frame = newFrame;
            }
        }
    }
    

    注意,我删除了oldPoint,因为你似乎没有使用它。我还将newPoint 重命名为translation,因为它不是屏幕上的一个点,而是衡量您的手指在屏幕上移动(或平移)多少的量度。我还将oldRect 重命名为newFrame,因为我认为它更准确地捕捉到了它的本质。

    基本上,我试图保留您的例程的逻辑,但只是澄清您的逻辑和变量名称。我原以为您可能需要一个额外的else if 原因,检查结束或取消的手势,使用动画来完成或适当地反转手势,但我没有解决这个问题,因为您没有在您的原始问题。

    无论如何,我希望您了解我们在这里所做的事情。我们正在保存原始帧并将翻译应用于该帧,而不是将其应用于当前帧。


    更新:

    在后续问题中,您询问了如何澄清动画。你可能会这样做:

    -(void) panningMyView:(UIPanGestureRecognizer*) panGesture
    {
        static CGRect originalFrame; // or you could make this a non-static class ivar
        CGPoint translation = [panGesture translationInView:self.view];
    
        if (panGesture.state == UIGestureRecognizerStateBegan)
        {
            originalFrame = self.myPanningView.frame;
        }
        else if (panGesture.state == UIGestureRecognizerStateChanged)
        {
            if (translation.x > 0) {
                CGRect newFrame = originalFrame;
                newFrame.size.width += translation.x;
                newFrame.size.height += translation.y;
                self.myPanningView.frame = newFrame;
            }
        }
        else if (panGesture.state == UIGestureRecognizerStateEnded ||
                 panGesture.state == UIGestureRecognizerStateCancelled ||
                 panGesture.state == UIGestureRecognizerStateFailed)
        {
            CGRect finalFrame = originalFrame;
    
            // if we've gone more than half way, move it all the way, 
            // otherwise return it to the original frame
    
            if (translation.x > (self.view.frame.size.width / 2.0))
            {
                finalFrame.size.width += self.view.frame.size.width;
                finalFrame.size.height += self.view.frame.size.height;
            }
    
            [UIView animateWithDuration:0.5
                                  delay:0.0
                                options:UIViewAnimationOptionCurveEaseOut
                             animations:^{
                                    self.myPanningView.frame = finalFrame;
                                 }
                             completion:nil];
        }
    }
    

    【讨论】:

    • 很好的解释,我搞砸了术语。但是,你说得很清楚。
    • 一切都在 stateChanged 中处理,所以在结束状态下,可以显示什么样的动画,最后一帧尺寸在 stateChanged 中设置。
    • @andyPaul 我已经用另一个添加手势结束动画的示例更新了我的答案。我建议的是一些逻辑,“嘿,如果我超过一半,将finalFrame设置为最终帧大小,然后设置动画。如果不超过一半,则为返回设置动画回到原来的大小”。显然,我不知道合适的finalFrame.size 值是多少,所以我做了一个猜测,但你必须改变它(以及if 声明,关于translation 有多少符合“超过一半”),但你明白了。
    • 罗布 我明白了。但是,我试图通过突出显示其边框来显示动画,代码在pastebin.com/BW4UYiM2...But,动画不显示
    • @andyPaul 好的,看起来您不想完成用户的手势,而是想让边框颜色瞬间闪烁红色。没关系,但如果您使用 CALayer 属性,如 borderColor,那是不可动画的。所以你必须使用transitionWithView 而不是animateWithDuration。我也鼓励你尝试options 的值UIViewAnimationOptionAutoreverse | UIViewAnimationOptionTransitionCrossDissolve 来润色效果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    • 2014-07-10
    相关资源
    最近更新 更多