代码之家  ›  专栏  ›  技术社区  ›  cameron

iPhone UIImageView收缩缩放

  •  4
  • cameron  · 技术社区  · 16 年前

    我一直在尝试使用CGSCALE为PhotoView(一个UIImageView实例)实现收缩放大/缩小(规划使用旋转,因此无法使用帧进行缩放,并将添加子视图,因此我认为UIScrollView将更加复杂)。无论如何,这个概念很容易理解,代码很快就组合起来了……从那时起,我一直在尝试解决同样的两个问题(相关?!)问题,使用三种不同的方法,但无法做到: 2-触摸点1和触摸点2在每次移动时都会前后跳跃几个像素,导致图像连续快速地缩小和放大,尽管总体效果是用户想要的缩小或放大(iPhone和模拟器)。

    代码如下:

    #import "PhotoView.h"
    
    
    @implementation PhotoView;
    @synthesize originalCenter, distance, zooming;
    - (id)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
        // Initialization code
            self.userInteractionEnabled = YES;
            self.multipleTouchEnabled = YES;
            zooming = NO;
        }
        return self;
    }
    
    float distanceBetweenTwoPoints(CGPoint point1, CGPoint point2)
    {
     NSLog(@"point1 x: %5.2f point 2 x: %5.2f ---- point 1 y: %5.2f  point 2 y:    %5.2f",point1.x,point2.x,point1.y,point2.y);
        return (sqrt(pow(point1.x -point2.x,2) + pow(point1.y - point2.y,2)));
    }
    -(void) touchesBegan: (NSSet *) touches withEvent:(UIEvent *) event {
    
        if ([touches count] > 1) {
    
          NSLog(@"^^^^^^^^^^^^^^^Tocuhes began with double touch!");
    
          distance = distanceBetweenTwoPoints([[[touches allObjects] objectAtIndex:0] locationInView:self], 
            [[[touches allObjects] objectAtIndex:1] locationInView:self]);
          zooming = YES;
        }
        else {
           zooming = NO;
           origianlCenter = [[[touches allObjects] objectAtIndex:0] locationInView:self];
           NSLog(@">>>>>>>>>>>>Touches began with single touch");
        }
    }
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    
        if (zooming) NSLog(@"!!!!!!!!!end zoom!!!!!!!");
    
        zooming = NO;
        if ([[touches anyObject] tapCount] == 2) {
            UITouch *thisTouch = [touches anyObject];
            CGPoint thisPoint = [thisTouch locationInView:self];
        }
    }
    
    - (void) touchesMoved: (NSSet *) touches withEvent:(UIEvent *) event {
        if ([touches count] > 1 && zooming) { // ignore if user added a second finger touch
            float distanceNew = distanceBetweenTwoPoints([[[touches allObjects] objectAtIndex:0]     locationInView:self], 
                     [[[touches allObjects] objectAtIndex:1] locationInView:self]);  
            if (distance <= 0.f) {    // should never be true - but it is sometimes!!!
               distance = distanceNew;
            }  
            float delta = 1.0f + ((distanceNew-distance)/distance);
            self.transform = CGAffineTransformScale(self.transform, delta, delta);
            distance = distanceNew;
        }
        else {
           if (zooming) {
              NSLog(@"*************shouldn't be here********* %d",[touches count]);
              return;
           }
           CGPoint thisPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self];
           self.transform = CGAffineTransformTranslate(self.transform, thisPoint.x-originalCenter.x, thisPoint.y-originalCenter.y);
    
        }
    }
    - (void)dealloc {
        [super dealloc];
    }
    @end
    

    日志示例:

    ^^^^^^^^^^^^^^^Tocuhes began with double touch!
    point1 x: 87.33 point 2 x: 235.63 ---- point 1 y: 322.30  point 2 y: 117.09
    point1 x: 90.76 point 2 x: 232.02 ---- point 1 y: 318.29  point 2 y: 123.51
    point1 x: 86.22 point 2 x: 236.71 ---- point 1 y: 323.30  point 2 y: 117.42
    point1 x: 89.51 point 2 x: 232.38 ---- point 1 y: 319.47  point 2 y: 123.47
    point1 x: 84.97 point 2 x: 237.02 ---- point 1 y: 324.48  point 2 y: 116.56
    *************shouldn't be here********* 1
    point1 x: 88.49 point 2 x: 232.52 ---- point 1 y: 321.27  point 2 y: 122.91
    *************shouldn't be here********* 1
    point1 x: 83.95 point 2 x: 237.11 ---- point 1 y: 327.21  point 2 y: 116.96
    !!!!!!!!!end zoom!!!!!!!
    

    我开始怀疑,我正在失去接触点的轨道,因为规模;然而,我在网上没有发现任何东西表明这是一个问题。任何线索(包括“阅读xyz上的文档”)都将不胜感激!

    提前谢谢。

    2 回复  |  直到 16 年前
        1
  •  6
  •   Frank Krueger    16 年前

    一般来说,每当您实现一个连续的UI行为时,您都需要根据不变的东西来度量它。

    因此,如果您的触摸导致视图转换发生更改,则应根据不变的内容(例如,您的父视图)测量触摸。因此,与其打电话:

    [touch locationInView:self]
    

    你应该使用

    [touch locationInView:[self superview]]
    

    我不确定这是否能解决你的问题,但它会消除你麻烦的一个可能原因。

        2
  •  17
  •   crafterm    16 年前

    viewForZoomingInScrollView: 方法,并设置 maximumZoomScale minimumZoomScale 属性,您就可以进行收缩缩放,而无需自己执行设置变换的计算?我刚刚在最近的一个项目中做了这个,效果很好。