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

Posted

技术标签:

【中文标题】图像未放大时如何停止移动图像?【英文标题】:how to stop moving image when image is not zoomed in? 【发布时间】:2015-11-02 11:14:36 【问题描述】:

我有一个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 应该只在图像缩放时移动,否则它不应该是可移动的。

【问题讨论】:

完成 - 我猜你欠我两个赏金好友;) 【参考方案1】:

我建议一种不同的方法:

创建一个UIScrollViewUIImageView 添加到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;
    

【讨论】:

如果它解决了你的问题,你能把它标记为正确答案吗?【参考方案2】:

我重新发布了我在您关于该主题的第一个问题 (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

【讨论】:

【参考方案3】:

您可以检查 imageView 的框架,如果相同,则表示 imageview 尚未缩放因此,如果 imageview 的框架相同,您可以禁用平移手势......如果框架已更改,那么您可以启用平移手势.....

【讨论】:

以上是关于图像未放大时如何停止移动图像?的主要内容,如果未能解决你的问题,请参考以下文章

不幸的是,当在android中通过横向模式捕获图像时,图像未旋转已停止?

Soundpool 停止问题?

按下“停止”按钮时如何停止动画并冻结图像

当对象移动到某个帧时如何停止 UIPanGestureRecognizer

图像缩放时在 UIScrollView 中停止滚动图像

如果我快速移动鼠标,如何停止对角渐变?