首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确实现可拖拽的“抽屉”自定义UIView

如何正确实现可拖拽的“抽屉”自定义UIView
EN

Stack Overflow用户
提问于 2014-01-11 04:25:57
回答 1查看 642关注 0票数 0

我在视图控制器的底部有一个自定义的UIView,它充当一个“抽屉”控件。视图的大约90个像素是可见的。当用户点击视图时,它会向上显示其他选项、控件等。再次点击后,视图会向下动画回到其原始位置。有效地“关闭抽屉”。

我还实现了代码,以便视图可以通过拖动手势进行跟踪:

代码语言:javascript
复制
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    if(self.frame.origin.y >= 80) {
        UITouch *theTouch = [touches anyObject];
        CGPoint location = [theTouch locationInView:self];
        CGPoint previousLocation = [theTouch previousLocationInView:self];
        CGFloat target = location.y - previousLocation.y;
        self.frame = CGRectOffset(self.frame, 0, target);
    }
}

所有这些都像预期的那样工作。但是,视图不能正确响应快速的“轻击”手势。在touchesEnded:withEvent:方法中,我对用户将手指指向其目的地的位置进行了动画处理。如果用户拖得很慢,然后松开,这样做效果很好。但如果它们快速闪烁,视图仍然需要处理0.5秒的持续时间,这对眼睛来说并不平滑。下面是自定义视图的所有代码:

代码语言:javascript
复制
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    if(self.frame.origin.y >= 80) {
        UITouch *theTouch = [touches anyObject];
        CGPoint location = [theTouch locationInView:self];
        CGPoint previousLocation = [theTouch previousLocationInView:self];
        CGFloat target = location.y - previousLocation.y;
        self.frame = CGRectOffset(self.frame, 0, target);
    }
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if(self.frame.origin.y == kDefaultUpY) {
        _comingFromUp = YES;
        _comingFromDown = NO;
    }
    else if(self.frame.origin.y == kDefaultDownY) {
        _comingFromUp = NO;
        _comingFromDown = YES;
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    //responding to tap
    if(self.frame.origin.y == kDefaultUpY) {
        [UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
            self.frame = CGRectMake(0, kDefaultDownY, self.frame.size.width, self.frame.size.height);
        } completion:nil];

        return;
    }
    else if(self.frame.origin.y == kDefaultDownY) {
        [UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
            self.frame = CGRectMake(0, kDefaultUpY, self.frame.size.width, self.frame.size.height);
        } completion:nil];

        return;
    }

    //responding to drag
    if(_comingFromDown) {
        if(self.frame.origin.y < kDefaultDownY) {
            //dragging up -- go up
            [UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
                self.frame = CGRectMake(0, kDefaultUpY, self.frame.size.width, self.frame.size.height);
            } completion:nil];
        }
        else if(self.frame.origin.y > kDefaultDownY) {
            //dragging down -- stay down
            [UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
                self.frame = CGRectMake(0, kDefaultDownY, self.frame.size.width, self.frame.size.height);
            } completion:nil];
        }
    }
    else if(_comingFromUp) {
        if(self.frame.origin.y < kDefaultUpY) {
            //dragging up -- stay up
            [UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
                self.frame = CGRectMake(0, kDefaultUpY, self.frame.size.width, self.frame.size.height);
            } completion:nil];
        }
        else if(self.frame.origin.y > kDefaultUpY) {
            //dragging down -- go down
            [UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
                self.frame = CGRectMake(0, kDefaultDownY, self.frame.size.width, self.frame.size.height);
            } completion:nil];
        }
    }
}

如何正确地响应与“折叠式”视图关联的手势?有没有一种标准的方法来实现这种功能?

EN

回答 1

Stack Overflow用户

发布于 2014-01-11 04:31:21

使用手势识别器,而不是自己实现触摸处理代码。您可以附加一个滑动手势识别器和一个平移手势识别器,并设置平移手势,以便在触发平移之前滑动必须失败。使划动手势的动画速度更快。像0.1秒或0.2秒这样的时间可能是正确的滑动手势。

不过,需要注意的是:在iOS 7中,屏幕底部的滑动手势会触发系统设置抽屉从屏幕底部弹出。我们的应用程序Face Dancer有一个控件抽屉,我们最近发现在iOS 7下很难在不触发系统设置抽屉的情况下将控件抽屉向上滑动。我们有一个用于拖动的“拇指”区域,我们正在添加一个点击手势,它将在一步中完全显示/隐藏它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21053764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档