hpique
hpique

Reputation: 120324

Scale with CGAffineTransform and set the anchor

If I understand correctly scaling a UIView with CGAffineTransform anchors the transformation to its center.

In particular:

self.frame = CGRectMake(0,0,100,100);
self.transform = CGAffineTransformMakeScale(2, 2);
NSLog(@"%f;%f;%f;%f", self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height); 

Prints:

-50;-50;200;200

How do you create a CGAffineTransform scale that uses a specific anchor point (say 0;0)?

Upvotes: 36

Views: 68963

Answers (3)

nivbp
nivbp

Reputation: 465

This is the way I found the scale a view while keeping it's origin in place (0,0) in Swift5

func animate() {
    myView.setAnchorPoint(CGPoint(x: 0, y: 0))
    myView.transform = CGAffineTransform(translationX: -0.5, y: -0.5)
    let animator = UIViewPropertyAnimator(duration: 0.3, curve: .easeOut) {
        self.myView.transform = CGAffineTransform(scaleX: 0.25, y: 0.25)
    }
}

extension UIView {
func setAnchorPoint(_ point: CGPoint) {
    var newPoint = CGPoint(x: bounds.size.width * point.x, y: bounds.size.height * point.y)
    var oldPoint = CGPoint(x: bounds.size.width * layer.anchorPoint.x, y: bounds.size.height * layer.anchorPoint.y);

    newPoint = newPoint.applying(transform)
    oldPoint = oldPoint.applying(transform)

    var position = layer.position

    position.x -= oldPoint.x
    position.x += newPoint.x

    position.y -= oldPoint.y
    position.y += newPoint.y

    layer.position = position
    layer.anchorPoint = point
}
}

credit to Hacking with Swift

Upvotes: 5

Mudit Bajpai
Mudit Bajpai

Reputation: 3020

Firstly #import <QuartzCore/QuartzCore.h> and then set the anchor points of your view:

   [[self layer] setAnchorPoint:CGPointMake(0, 0)];

Upvotes: 4

deanWombourne
deanWombourne

Reputation: 38475

(a)

Scale and then translate?

Something like :

CGAffineTransform t = CGAffineTransformMakeScale(2, 2);
t = CGAffineTransformTranslate(t, width/2, height/2);
self.transform = t;

(b)

Set the anchor point (which is probably what you want really)

[self layer].anchorPoint = CGPointMake(0.0f, 0.0f);
self.transform = CGAffineTransformMakeScale(2, 2);

(c)

Set the center again to make sure it's in the same place?

CGPoint center = self.center;
self.transform = CGAffineTransformMakeScale(2, 2);
self.center = center;

Upvotes: 74

Related Questions