I want to alter the anchorPoint
, but keep the view in the same place.
I've tried NSLog
-ing self.layer.position
and self.center
and they both stay the same regardless of changes to the anchorPoint. Yet my view moves!
Any tips on how to do this?
self.layer.anchorPoint = CGPointMake(0.5, 0.5);
NSLog(@"center point: %f %f", self.layer.position.x, self.layer.position.y);
self.layer.anchorPoint = CGPointMake(1, 1);
NSLog(@"center point: %f %f", self.layer.position.x, self.layer.position.y);
The output is:
2009-12-27 20:43:24.161 Type[11289:207] center point: 272.500000 242.500000
2009-12-27 20:43:24.162 Type[11289:207] center point: 272.500000 242.500000
If you change anchorPoint, its position will change too, UNLESS you origin is zero point
CGPointZero
.I had the same problem. Brad Larson's solution worked great even when the view is rotated. Here is his solution translated into code.
And the swift equivalent:
There is such a simple solution. This is based on Kenny's answer. But instead of applying the old frame, use it's origin and the new ones to calculate the transition, then apply that transition to the center. It works with rotated view too! Here's the code, a lot simpler than other solutions:
And the Swift version:
The key to solving this was to use the frame property, which is weirdly the only thing that changes.
Swift 2
Swift 3
Then I do my resize, where it scales from the anchorPoint. Then I have to restore the old anchorPoint;
Swift 2
Swift 3
EDIT: this flakes out if the view is rotated, as the frame property is undefined if a CGAffineTransform has been applied.
Here is user945711's answer adjusted for NSView on OS X. Besides NSView not having a
.center
property, the NSView's frame doesn't change (probably because NSViews do not come with a CALayer by default) but the CALayer frame origin changes when the anchorPoint is changed.The Layer Geometry and Transforms section of the Core Animation Programming Guide explains the relationship between a CALayer's position and anchorPoint properties. Basically, the position of a layer is specified in terms of the location of the layer's anchorPoint. By default, a layer's anchorPoint is (0.5, 0.5), which lies at the center of the layer. When you set the position of the layer, you are then setting the location of the center of the layer in its superlayer's coordinate system.
Because the position is relative to the anchorPoint of the layer, changing that anchorPoint while maintaining the same position moves the layer. In order to prevent this movement, you would need to adjust the layer's position to account for the new anchorPoint. One way I've done this is to grab the layer's bounds, multiply the bounds' width and height by the old and new anchorPoint's normalized values, take the difference of the two anchorPoints, and apply that difference to the position of the layer.
You might even be able to account for rotation this way by using
CGPointApplyAffineTransform()
with your UIView's CGAffineTransform.