拖动时根据 x 坐标缩放视图

Posted

技术标签:

【中文标题】拖动时根据 x 坐标缩放视图【英文标题】:Scaling view depending on x coordinate while being dragged 【发布时间】:2014-12-03 22:35:43 【问题描述】:

我一直在尝试实现一个 UI 功能,我在一些使用卡片显示信息的应用程序中看到了这种功能。我当前的视图控制器如下所示:

并且用户可以沿 x 轴左右拖动卡片。拖动到屏幕的右侧对卡片的比例没有任何影响(只是改变位置)但是如果用户向左滑动它我想根据它的 y 坐标慢慢减小它的比例(例如比例是最小的当卡片向左最远时,从该点开始变大,直到达到原始大小)。如果卡片被拖到左边足够远,它会淡出,但如果用户没有将它拖得足够远,它的比例会增加并移回中间。到目前为止我尝试过的代码:

- (void)handlePanImage:(UIPanGestureRecognizer *)sender

    static CGPoint originalCenter;

    if (sender.state == UIGestureRecognizerStateBegan)
    
        originalCenter = sender.view.center;
        sender.view.alpha = 0.8;
        [sender.view.superview bringSubviewToFront:sender.view];
    
    else if (sender.state == UIGestureRecognizerStateChanged)
    
        CGPoint translation = [sender translationInView:self.view];
        NSLog(@"%f x %f y",translation.x ,translation.y);
        sender.view.center=CGPointMake(originalCenter.x + translation.x, yOfView);
        CGAffineTransform transform = sender.view.transform;
        i-=0.001;
        transform = CGAffineTransformScale(transform, i, i);
        //transform = CGAffineTransformRotate(transform, self.rotationAngle);
        sender.view.transform = transform;
    
    else if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateCancelled || sender.state == UIGestureRecognizerStateFailed)
    
        if(sender.view.center.x>0)
            [UIView animateWithDuration:0.2 animations:^
                CGRect rect=[sender.view frame];
                rect.origin.x=([self.view frame].size.width/2)-_protoypeView.frame.size.width/2;
                rect.size.height=originalHeight;
                rect.size.width=originalWidth;
                [sender.view setFrame:rect];
                i=1.0;

            ];
        
        [UIView animateWithDuration:0.1 animations:^
            sender.view.alpha  = 1.0;
        ];
    

这看起来非常有问题并且不能正常工作。我也尝试根据翻译改变比例:

else if (sender.state == UIGestureRecognizerStateChanged)
    
        CGPoint translation = [sender translationInView:self.view];
        NSLog(@"%f x %f y",translation.x ,translation.y);
        sender.view.center=CGPointMake(originalCenter.x + translation.x, yOfView);
        CGAffineTransform transform = sender.view.transform;
        transform = CGAffineTransformScale(transform, translation.x/100, translation.x/100);
        //transform = CGAffineTransformRotate(transform, self.rotationAngle);
        sender.view.transform = transform;
    

但比例尺要么太大要么太小。任何帮助将不胜感激:)

【问题讨论】:

【参考方案1】:

在您尝试的最后一段代码中,您做错了几件事。缩放变换将是累积的,因为您从未将平移手势识别器的平移设置回 0。此外,如果您查看变换中的数学运算,您会发现 -1 点的小移动会缩放视图到原来大小的 0.01 倍。你显然不想那样。您需要将那个小的负数加到 1,这样初始的 -1 点移动将缩放到 0.99。将平移器的平移设置回零的更改需要更改中心计算以使用 sender.view.center.x 而不是 originalCenter.X。您还需要一个 if 语句来检查中心是在其起始位置的左侧还是右侧,以便您知道是否应该应用缩放变换。像这样的,

-(void)handlePan:(UIPanGestureRecognizer *) sender 
    if (sender.state == UIGestureRecognizerStateBegan) 
        originalCenter = sender.view.center;
        sender.view.alpha = 0.8;
        [sender.view.superview bringSubviewToFront:sender.view];

    else if (sender.state == UIGestureRecognizerStateChanged)
        CGPoint translation = [sender translationInView:self.view];
        sender.view.center=CGPointMake(sender.view.center.x + translation.x, sender.view.center.y);
        if (sender.view.center.x < originalCenter.x) 
            CGAffineTransform transform = sender.view.transform;
            transform = CGAffineTransformScale(transform, 1+translation.x/100.0, 1+translation.x/100.0);
            sender.view.transform = transform;
        
        [sender setTranslation:CGPointZero inView:self.view];
    

这不负责将视图动画化或淡出视图,但它应该可以让您大部分时间到达那里。

【讨论】:

这对于视图的比例部分非常有效,但我似乎无法让它恢复到原来的大小。将比例转换为 1,1 没有效果并且 CGRect rect2=[sender.view frame]; rect2.size.height=原始高度; rect2.size.width=原始宽度; [sender.view setFrame:rect2];在 sender.state == UIGestureRecognizerStateEnded 中调用时使视图整体消失。

以上是关于拖动时根据 x 坐标缩放视图的主要内容,如果未能解决你的问题,请参考以下文章

OpenLayers根据输入坐标居中显示功能

如何忽略缩放图像视图 Swift 3

从 TouchesMoved 获取子视图参考

百度地图API一:根据标注点坐标范围计算显示缩放级别zoom自适应显示地图

MapView 以用户坐标为中心缩放

如何通过拖动视图边缘/角来实现缩放,如应用官方照片应用裁剪控制?