Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CGAffineTransformMakeScale Makes UIView Jump to Original Size before scale

I have a UIView that I set up to respond to pinch gestures and change its size, except, once you enlarge it and then try and pinch it again, it jumps to its original size (which just so happens to be 100x200). Here is the code:

@implementation ChartAxisView


- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // do gesture recognizers
        UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(onPinch:)]; 
        [self addGestureRecognizer:pinch]; 
        [pinch release];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGColorRef redColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0].CGColor;

    CGContextSetFillColorWithColor(context, redColor);
    CGContextFillRect(context, self.bounds);
}

- (void)onPinch: (UIPinchGestureRecognizer*) gesture {  
    self.transform = CGAffineTransformMakeScale(gesture.scale, gesture.scale);
}

- (void)dealloc {
    [super dealloc];
}


@end

Any thoughts?

like image 664
jps Avatar asked Oct 15 '10 23:10

jps


3 Answers

So there are two types of Scale (or, transform in general) functions: CGAffineTransformMakeScale and CGAffineTransformScale

The first one, CGAffineTransformMakeScale which you are using, always transforms with respect to the image's original size. And that is why you see the jump to its original size before the scaling happens.

The second one, CGAffineTransformScale, transforms from the image's current position. This is what you need. For this, it requires an additional 'transform' arg. The 'transform' arg in your case represents the enlarged image.

Read this very informative blog post about transformations.

like image 59
Mihir Mathuria Avatar answered Nov 02 '22 05:11

Mihir Mathuria


- (void)onPinch: (UIPinchGestureRecognizer*) gesture {  

  if ([gesture state] == UIGestureRecognizerStateBegan) 
  {
    curTransform = self.transform;
  }

  self.transform = CGAffineTransformScale(curTransform,gesture.scale, gesture.scale);
}
  • use CGAffineTransformScale instead of CGAffineTransformMakeScale
  • you will need a member -> CGAffineTransform curTransform;

;)

like image 26
muggel Avatar answered Nov 02 '22 06:11

muggel


you can set transform with following code:

ivClone setTransform:CGAffineTransformMakeScale(scale, scale)];

and you can get current transform with following coee:

newV.transform.a //x scale
newV.transform.d // y scale
like image 2
ygweric Avatar answered Nov 02 '22 06:11

ygweric