如何在图像未放大时停止移动图像?

时间:2015-11-02 11:14:37

标签: ios objective-c iphone uiimageview uiimage

我有UIImageView我正在进行捏缩放&在完全变焦时移动图像。我能够移动图像,但问题是即使图像没有放大,它仍然在屏幕上移动。请告诉我如何防止它?

以下是

的代码
#define MINIMUM_SCALE 0.5
#define MAXIMUM_SCALE 6.0
@property CGPoint translation;


- (void)pan:(UIPanGestureRecognizer *)gesture {
    static CGPoint currentTranslation;
    static CGFloat currentScale = 0;
    if (gesture.state == UIGestureRecognizerStateBegan) {
        currentTranslation = _translation;
        currentScale = self.view.frame.size.width / self.view.bounds.size.width;
    }
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {

        CGPoint translation = [gesture translationInView:self.view];

        _translation.x = translation.x + currentTranslation.x;
        _translation.y = translation.y + currentTranslation.y;
        CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x , _translation.y);
        CGAffineTransform transform2 = CGAffineTransformMakeScale(currentScale, currentScale);
        CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
        self.view.transform = transform;
    }
}


- (void)pinch:(UIPinchGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {
//        NSLog(@"gesture.scale = %f", gesture.scale);

        CGFloat currentScale = self.view.frame.size.width / self.view.bounds.size.width;
        CGFloat newScale = currentScale * gesture.scale;

        if (newScale < MINIMUM_SCALE) {
            newScale = MINIMUM_SCALE;
        }
        if (newScale > MAXIMUM_SCALE) {
            newScale = MAXIMUM_SCALE;
        }

        CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x, _translation.y);
        CGAffineTransform transform2 = CGAffineTransformMakeScale(newScale, newScale);
        CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
        self.view.transform = transform;
        gesture.scale = 1;
    }
}

** PS:** ImageView只应在图像缩放时移动,否则不应移动。

3 个答案:

答案 0 :(得分:4)

我建议采用不同的方法:

创建SetUIScrollView添加到scrollView&#39; UIImageView中,并允许滚动和缩放scrollView。

要防止在未缩放时滚动,请将contentView设置为setScrollEnabled,如果zoomLevel达到自定义阈值,则在NO中启用它。

所以......像这样可以让你更轻松地尝试用更少的代码来完成。

scrollViewDidZoom

答案 1 :(得分:1)

我在你关于这个主题的第一个问题(Pinch zoom shifting image to most left corner on iPad in iOS?)中重新发布了我给你的代码,因为我认为你这样做的方式不能按预期工作(就我测试而言)。

缩放变焦应该放大手指的中间位置,而不是放在图像的中间位置。如果你真的想在中心应用缩放,我添加了一个布尔属性zoomOnCenter。

边界检查在translateBy方法中完成。

以下是xCode测试项目的链接:https://drive.google.com/file/d/0B88aMtNA0z2aWVBIbGZGdVhpdWM/view?usp=sharing

<强>接口

@interface PinchViewController : UIViewController

@property(nonatomic,strong) IBOutlet UIView* contentView;
@property(nonatomic,assign) BOOL zoomOnCenter;

@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.zoomOnCenter ? CGPointZero : [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];
}

- (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];
}


-(void)translateBy:(CGPoint)delta
{
    CGSize contentSize = self.contentView.bounds.size;
    CGSize viewSize = self.view.bounds.size;
    CGSize  scaledViewSize = viewSize;
    scaledViewSize.width/=scale;
    scaledViewSize.height/=scale;
    CGPoint maxTranslation = CGPointMake( (contentSize.width-scaledViewSize.width) / 2.0f , (contentSize.height-scaledViewSize.height) / 2.0f );

    if ( contentSize.width*scale < viewSize.width ) {
        delta.x=0;
        translation.x = 0;
    } else {
        translation.x+=delta.x;
        if ( translation.x < - maxTranslation.x ) {
            translation.x = - maxTranslation.x;
        }
        else if ( translation.x > maxTranslation.x ) {
            translation.x = maxTranslation.x;
        }
    }

    if ( contentSize.height*scale < viewSize.height ) {
        delta.y=0; translation.y = 0;
    } else {
        translation.y+=delta.y;
        if ( translation.y < - maxTranslation.y ) {
            translation.y = - maxTranslation.y;
        }
        else if ( translation.y > maxTranslation.y ) {
            translation.y = maxTranslation.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

答案 2 :(得分:1)

你可以检查你的imageView的帧,如果它是相同的,这意味着imageview还没有被缩放所以你可以禁用平移手势,如果imageview的帧是相同的......如果帧已经改变那么你可以启用平移手势.....