gpt4 book ai didi

ios - UIPanGestureRecognizer 状态结束后动画中的小问题

转载 作者:行者123 更新时间:2023-12-01 17:39:21 24 4
gpt4 key购买 nike

我正在尝试实现 View 的拖动,当拖动停止时, View 滑到顶部并消失。我可以使用 UIPanGestureRecognizer 很好地拖动 View 。但在那之后,我用动画让它滑出。问题是在拖动之后,在 View 移动之前总是会有一点小问题......我四处搜索,无法弄清楚如何解决这个问题。这是代码:

- (void)moveView2:(UIPanGestureRecognizer *)pan {    
CGPoint delta = [pan translationInView:self.view];
CGPoint newCenter = CGPointMake(_view2.center.x, _view2.center.y + delta.y);
_view2.center = newCenter;
[pan setTranslation:CGPointZero inView:self.view];
if (pan.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [pan velocityInView:self.view];
NSLog(@"Velocity is %f, %f", velocity.x, velocity.y);
// Here is the delay
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.5f initialSpringVelocity:500 options:UIViewAnimationOptionCurveEaseInOut animations:^{
_view2.center = CGPointMake(_view2.center.x, -600);
} completion:nil];
}





#import "ViewController.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIButton *fbButton;

@property (weak, nonatomic) IBOutlet UIButton *twitterButton;

@property UIView *view1;
@property UIView *view2;

@property CGPoint startPoint;
@property CGPoint endPoint;
@property CGPoint originCenter;

@property double startTime;
@property double endTime;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
CGRect frame = [UIScreen mainScreen].bounds;
_view1 = [[UIView alloc] initWithFrame:frame];
_view1.backgroundColor = [UIColor redColor];
[self.view addSubview:_view1];
_view2 = [[UIView alloc] initWithFrame:frame];
_view2.backgroundColor = [UIColor greenColor];
[self.view addSubview:_view2];
UIPanGestureRecognizer *pan1 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveView2:)];
[_view2 addGestureRecognizer:pan1];
/*
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeUpDown:)];
[swipe setDirection:UISwipeGestureRecognizerDirectionUp];
[_view2 addGestureRecognizer:swipe];
*/
}

/*
- (void)swipeUpDown:(UISwipeGestureRecognizer *)swipe {
if (swipe.direction == UISwipeGestureRecognizerDirectionUp) {
NSLog(@"Swipe up");
[UIView animateWithDuration:0.5 animations:^{
_view2.center = CGPointMake(_view2.center.x, -600);
}];
}
}*/

- (void)moveView2:(UIPanGestureRecognizer *)pan {
CGPoint bigViewDelta = [pan translationInView:self.view];
CGPoint newCenter = CGPointMake(_view2.center.x, _view2.center.y + bigViewDelta.y);
_view2.center = newCenter;
[pan setTranslation:CGPointZero inView:self.view];
if (pan.state == UIGestureRecognizerStateEnded) {
CGPoint velocityOfPan = [pan velocityInView:self.view];
CGFloat velocityOfPanAbsolute = sqrt(velocityOfPan.x * velocityOfPan.x + velocityOfPan.y * velocityOfPan.y);
// get simple points per second
CGPoint currentPoint = _view2.center;
CGPoint finalPoint = CGPointMake(_view2.center.x, -600);
CGFloat distance = sqrt((finalPoint.x - currentPoint.x) * (finalPoint.x - currentPoint.x) + (finalPoint.y - currentPoint.y) * (finalPoint.y - currentPoint.y));
// how far to travel
CGFloat duration = 0.5;
CGFloat animationVelocity = velocityOfPanAbsolute / (distance / duration);

[UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:1.0 initialSpringVelocity:animationVelocity options:0 animations:^{
_view2.center = CGPointMake(_view2.center.x, -600);
} completion:nil]; }
}

- (void)viewDidAppear:(BOOL)animated {
/*
[UIView transitionFromView:_view2 toView:_view1 duration:2 options:UIViewAnimationOptionCurveEaseInOut completion:^(BOOL finished) {
}];
*/

/*
// get the view that's currently showing
UIView *currentView = _view2;
// get the the underlying UIWindow, or the view containing the current view view
UIView *theWindow = [currentView superview];
// remove the current view and replace with myView1
[currentView removeFromSuperview];
//[theWindow addSubview:newView];
// set up an animation for the transition between the views
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[theWindow layer] addAnimation:animation forKey:@"SwitchToView1"];
*/
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

最佳答案

你的意思是动画发生之前的延迟?嗯,我没有看到任何会导致这种情况的东西,但是 animateWithDuration 的参数非常非常好奇。

  • 一、UIViewAnimationOptionCurveEaseInOut对我来说没有意义,因为这常用于说“慢慢开始,加快速度,也慢慢停止”。这对于一个标准动画来说很好,您不希望动画的开始过于刺耳。但这在这种情况下没有意义,因为您可能希望它不要缓慢启动,而是使用您最初提供的任何速度。如果我使用任何 option , 我会使用 UIViewAnimationOptionCurveEaseOut .即使这样也没有意义,因为它是 usingSpringWithDamping指示在此动画结束时发生的情况的参数。 (而且,最重要的是,您将其拖出屏幕,所以我不清楚您为什么关心退出曲线。)
  • 二、initialSpringVelocity对我来说似乎也不对。正如此参数的文档所述:

    The initial spring velocity. For smooth start to the animation, match this value to the view’s velocity as it was prior to attachment.

    A value of 1 corresponds to the total animation distance traversed in one second. For example, if the total animation distance is 200 points and you want the start of the animation to match a view velocity of 100 pt/s, use a value of 0.5.



    所以,500表示您想在一秒钟内从当前位置到最终位置的距离旅行 500 倍。这快得离谱。

    我会尝试将初始速度与手势的最终速度相匹配。因此,计算手势的绝对速度,然后将其除以要经过的距离除以动画的持续时间。
  • 第三,如果您将其拖出屏幕,我不确定您为什么要使用 usingSpringWithDamping0.5 .那是有弹性的。为什么你要让它在你正在使用的所有东西中弹出,因为它会停止在屏幕上并且你无论如何都看不到它?令我震惊的是,任何小于 1.0 的值在一个或多个初始弹跳期间, View 可能会弹回可见屏幕。我不会使用低于 1.0 的任何东西如果在屏幕外设置动画。

  • 把所有这些放在一起,我得到了类似的东西:
    CGPoint velocityOfPan = [pan velocityInView:self.view];
    CGFloat velocityOfPanAbsolute = hypof(velocityOfPan.x, velocityOfPan.y); // get simple points per second
    CGPoint currentPoint = _view2.center.x;
    CGPoint finalPoint = CGPointMake(_view2.center.x, -600);
    CGFloat distance = hypof(finalPoint.x - currentPoint.x, finalPoint.y - currentPoint.y); // how far to travel
    CGFloat duration = 0.5;
    CGFloat animationVelocity = velocityOfPanAbsolute / (distance / duration);

    [UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:1.0 initialSpringVelocity:animationVelocity options:0 animations:^{
    _view2.center = CGPointMake(_view2.center.x, -600);
    } completion:nil];

    说了这么多,虽然有可能 animateWithDuration被“缓入缓出”和戏剧性的 initialSpringVelocity组合弄糊涂了,我实际上不明白为什么会导致“打嗝”。

    你在这个动画之后立即做其他事情吗?任何可能阻塞主队列的东西?

    你的意思是手势被第一次识别之前的一点延迟?是的,这是平移手势识别器的一个功能。 (我认为它试图确定它是否真的是平底锅 vs 长按 vs 等)。

    你可以通过使用 UILongPressGestureRecognizee 来解决这个问题。与 minimumPressDuration为零(尽管您必须自己计算 translationInView)。

    关于ios - UIPanGestureRecognizer 状态结束后动画中的小问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26623463/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com