【问题标题】:Pinch zoom shifting image to most left corner on iPad in iOS?在iOS中的iPad上捏缩放将图像移动到最左角?
【发布时间】:2016-01-30 17:14:14
【问题描述】:

我在 iOS 中有一张图片。当我捏住它移动到左上角的图像时,我在图像上添加了捏合手势。我还在图像上添加了平移手势。当图像被缩放时,我会向各个方向滚动图像,为此我已将平移手势添加到图像中。

我的代码是:

-(void)viewDidLoad
{
UIPinchGestureRecognizer *pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
            [self.zoom_image addGestureRecognizer:pinch];
            panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveImage:)];
            [panGesture setMinimumNumberOfTouches:1];
            [panGesture setMaximumNumberOfTouches:1];
            [self.zoom_image addGestureRecognizer:panGesture];

            img_center_x = self.zoom_image.center.x;
            img_center_y = self.zoom_image.center.y;

}

-(void)handlePinch:(UIPinchGestureRecognizer*)sender
{
    NSLog(@"latscale = %f",mLastScale);
    mCurrentScale += [sender scale] - mLastScale;
    mLastScale = [sender scale];
    NSLog(@"before ceneter x %f",img_center_x);
    NSLog(@"before ceneter x %f",img_center_y);
    CGPoint img_center = CGPointMake(img_center_x, img_center_y);
    self.zoom_image.center = img_center;
    if (sender.state == UIGestureRecognizerStateEnded)
    {
      mLastScale = 1.0;
    }
    if(mCurrentScale<1.0)
    {
        mCurrentScale=1.0;
    }
    if(mCurrentScale>3.0)
    {
        mCurrentScale=3.0;
    }
    CGAffineTransform currentTransform = CGAffineTransformIdentity;
    CGAffineTransform newTransform = CGAffineTransformScale(currentTransform,mCurrentScale, mCurrentScale);
    self.zoom_image.transform = newTransform;

}

平移手势

 UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveImage:)];
            [panGesture setMinimumNumberOfTouches:1];
            [panGesture setMaximumNumberOfTouches:1];
            [self.zoom_image addGestureRecognizer:panGesture];

move image:

- (void)moveImage:(UIPanGestureRecognizer *)recognizer
{
    CGPoint translation = [recognizer translationInView:self.zoom_image];
    CGPoint location = [recognizer locationInView:self.view];
    CGPoint initial=CGPointZero;
    NSLog(@"%f\n%f",translation.x,translation.y);
    NSLog(@"%f",self.zoom_image.frame.origin.y);
    CGPoint finalpoint = CGPointMake(self.zoom_image.center.x + translation.x, self.zoom_image.center.y+ translation.y);
    NSLog(@"%f",finalpoint.y);
    //limit the boundary
    if(recognizer.state==UIGestureRecognizerStateChanged)
    {
        if ((self.zoom_image.frame.origin.x>0 && translation.x > 0) || (self.zoom_image.frame.origin.x + self.zoom_image.frame.size.width<=self.view.frame.size.width && translation.x < 0))
            finalpoint.x = self.zoom_image.center.x;

        if ((self.zoom_image.frame.origin.y>100 && translation.y > 0) || (self.zoom_image.frame.origin.y + self.zoom_image.frame.size.height<=self.view.frame.size.height && translation.y < 0))
            finalpoint.y = self.zoom_image.center.y;
        //set final position
        NSLog(@"%f",finalpoint.y);
        self.zoom_image.center = finalpoint;
        [recognizer setTranslation:initial inView:self.zoom_image];
    }
}

【问题讨论】:

    标签: ios objective-c iphone ipad uipinchgesturerecognizer


    【解决方案1】:

    这是一个可能的解决方案。

    • 我已将您的 zoom_image 重命名为 contentView,因为此类可以操作任何视图,而不仅仅是图像。

    • 我已经删除了绑定测试,并将比例设为 (0.01 - 10.0)

    • 最多三个手指的捏合手柄,也可用作平移。可以在不中断捏合的情况下更改触摸次数。

    还有很多需要改进的地方,但主要的原则在这里:)

    接口(如 minScale、maxScale、minMargin 等属性仍有待添加 - 为什么不是委托)

    @interface PinchViewController : UIViewController
    
    @property(nonatomic,strong) IBOutlet UIView* contentView;
    
    @end
    

    实施

    @implementation PinchViewController
    {
        CGPoint translation;
        CGFloat scale;
    
        CGAffineTransform scaleTransform;
        CGAffineTransform translateTransform;
    
        CGPoint     previousTranslation;
        CGFloat     previousScale;
        NSUInteger  previousNumTouches;
    }
    
    -(void)viewDidLoad
    {
        scale = 1.0f;
        scaleTransform = CGAffineTransformIdentity;
        translateTransform = CGAffineTransformIdentity;
        previousTranslation = CGPointZero;
        previousNumTouches = 0;
    
        UIPinchGestureRecognizer *pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
        [self.view addGestureRecognizer:pinch];
    
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
        [panGesture setMinimumNumberOfTouches:1];
        [panGesture setMaximumNumberOfTouches:1];
        [self.view addGestureRecognizer:panGesture];
    
    }
    
    -(void)handlePinch:(UIPinchGestureRecognizer*)recognizer
    {
        // 1 - find pinch center
        CGPoint mid = [self computePinchCenter:recognizer];
        mid.x-= recognizer.view.bounds.size.width / 2.0f;
        mid.y-= recognizer.view.bounds.size.height / 2.0f;
    
        // 2 - compute deltas
        NSUInteger numTouches = recognizer.numberOfTouches;
        if ( (recognizer.state==UIGestureRecognizerStateBegan)  || ( previousNumTouches != numTouches ) ) {
            previousScale = recognizer.scale;
            previousTranslation = mid;
            previousNumTouches = numTouches;
        }
    
        CGFloat deltaScale = ( recognizer.scale - previousScale ) * scale;
        previousScale = recognizer.scale;
    
        CGPoint deltaTranslation = CGPointMake(mid.x-previousTranslation.x, mid.y-previousTranslation.y);
        previousTranslation = mid;
    
        deltaTranslation.x/=scale;
        deltaTranslation.y/=scale;
    
        // 3 - apply
        scale+=deltaScale;
    
        if (scale<0.01) scale = 0.01; else if (scale>10) scale = 10;
    
        scaleTransform = CGAffineTransformMakeScale(scale, scale);
        [self translateBy:deltaTranslation];
    
        NSLog(@"Translation : %.2f,%.2f - Scale Center : %.2f,%.2f - Scale : %.2f",deltaTranslation.x,deltaTranslation.y,mid.x,mid.y,scale);
    }
    
    - (void)handlePan:(UIPanGestureRecognizer *)recognizer
    {
        if (recognizer.state==UIGestureRecognizerStateBegan) previousTranslation = CGPointZero;
        CGPoint recognizerTranslation = [recognizer translationInView:self.contentView];
        CGPoint deltaTranslation = CGPointMake(recognizerTranslation.x - previousTranslation.x,recognizerTranslation.y - previousTranslation.y);
        previousTranslation = recognizerTranslation;
        [self translateBy:deltaTranslation];
    
        NSLog(@"Translation : %.2f,%.2f - Scale : %.2f",deltaTranslation.x,deltaTranslation.y,scale);
    }
    
    
    -(void)translateBy:(CGPoint)delta
    {
        translation.x+=delta.x;
        translation.y+=delta.y;
        translateTransform = CGAffineTransformMakeTranslation(translation.x,translation.y);
        self.contentView.transform = CGAffineTransformConcat(translateTransform,scaleTransform);
    }
    
    -(CGPoint)computePinchCenter:(UIPinchGestureRecognizer*)recognizer
    {
        // 1 - handle up to 3 touches
        NSUInteger numTouches = recognizer.numberOfTouches;
        if (numTouches>3) numTouches = 3;
    
        // 2 - Find fingers middle point - with (0,0) being the center of the view
        CGPoint pt1,pt2,pt3,mid;
        switch (numTouches) {
            case 3:
                pt3 = [recognizer locationOfTouch:2 inView:recognizer.view];
            case 2:
                pt2 = [recognizer locationOfTouch:1 inView:recognizer.view];
            case 1:
                pt1 = [recognizer locationOfTouch:0 inView:recognizer.view];
        }
        switch (numTouches) {
            case 3:
                mid = CGPointMake( ( ( pt1.x + pt2.x ) / 2.0f + pt3.x ) / 2.0f, ( ( pt1.y + pt2.y ) / 2.0f + pt3.y ) / 2.0f );
                break;
            case 2:
                mid = CGPointMake( ( pt1.x + pt2.x ) / 2.0f, ( pt1.y + pt2.y ) / 2.0f  );
                break;
            case 1:
                mid = CGPointMake( pt1.x, pt1.y);
                break;
        }
        return mid;
    }
    
    @end
    

    希望它会有所帮助:) 干杯

    【讨论】:

    • 对……这是一个快速的猜测。我已经睡过了。我用一种可能的方式进行编辑和替换。
    • 是的 - 第一个解决方案是快速猜测,但不起作用。编辑后的答案有效,并且仍然允许很多改进。
    • 有哪些改进?
    • 使用诸如 minScale、maxScale 之类的属性设置限制... 捏合算法已经很好地工作了,但是在缩放时手指的中心并不完全静止。它应该,但我不能花更多的时间在它上面:)
    • 顺便说一句,我投票赞成你的问题,因为那是一个有趣的挑战;)再见!
    猜你喜欢
    • 2017-08-16
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 2016-01-08
    相关资源
    最近更新 更多