2015-11-02 51 views
1

我有一个UIImageView我正在执行捏变焦&移动图像的全zoom.I能够移动图像,但问题是即使图像没有放大它仍然在屏幕上移动。请告诉我我怎么能阻止它?如何在图像未放大时停止移动图像?

下面是代码

#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只能移动。

+0

完成 - 我想你欠我两个赏金伙伴;) – Moose

回答

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 
1

您可以检查您的ImageView的,如果它的框架是相同的,这意味着imageview没有被放大所以你可以禁用泛手势如果ImageView的框架是相同的......如果框架已经改变,那么您可以启用移动手势.....

4

我提出一个不同的方法:

创建UIScrollView加将UIImageView纳入scrollView的contentView并允许在scrollView上滚动和缩放。

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

所以......像这样应该可以让你用更少的代码来完成你想要完成的任务。

- (void)viewDidLoad:(BOOL)animated { 
    [super viewDidLoad:animated]; 
    self.scrollView.scrollEnabled = NO; 
    self.scrollView.minimumZoomScale = 1; 
} 

- (void)scrollViewDidZoom:(UIScrollView *)scrollView { 
    if (scrollView.zoomLevel > 1) { 
     scrollView.scrollEnabled = YES; 
    } else { 
     scrollView.scrollEnabled = NO; 
    } 
} 
+0

如果能解决你的问题,你能把这个标记为正确答案吗? – MarkHim