使用CGAffineTransform进行缩放并设置锚点

35

如果我理解正确,使用CGAffineTransform缩放UIView将锚点设置为其中心。

具体来说:

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); 

输出:

-50;-50;200;200

如何创建一个 CGAffineTransform 缩放,使用特定的锚点(比如说 0;0)?


13
很奇怪,我使用的是iOS 7系统,但它并不会从中心进行缩放,而是从左上角开始缩放...即使我将锚点设置为(0.5, 0.5),它也不会从中心进行缩放。有没有人有什么想法? - Van Du Tran
2
@VanDuTran 我发现在视图的 layer 上使用 CATransform3D 可以正确地表现并遵守 anchorPoint。尝试使用它来替代 CGAffineTransformMakeScale,后者会将视图限制在窗口的顶部和左侧边界。 - Jonathan Lin
@JonathanLin 我使用带有CATransform3D的图层,在iOS 7上也没有成功。 - ZYiOS
3个回答

73

进行缩放和平移操作?

就像这样:

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

(b)

设置锚点(这可能是您真正想要的)

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

(c)

重新设置中心以确保其位于同一位置?
CGPoint center = self.center;
self.transform = CGAffineTransformMakeScale(2, 2);
self.center = center;

当然,我可以手动更改位置,但我更想更好地理解CGAffineTransform。 :) - hpique
4
不要忘记,如果你将翻译上升100像素,但是你的变换已经有2倍的缩放比例,那么你实际上需要向上平移200像素 - 在决定平移多远时,你必须考虑到缩放因子并进行相应的补偿! - deanWombourne
2
看一下这篇文章:http://iphonedevelopment.blogspot.com/2008/10/demystifying-cgaffinetransform.html - 我觉得它非常有帮助! - deanWombourne
2
经过几次测试,似乎(0,0)锚点的变换是:double scale = 2; double translateX = self.frame.size.width * (scale - 1)/2/scale; double translateY = self.frame.size.height * (scale - 1)/2/scale; CGAffineTransform t = CGAffineTransformMakeScale(scale, scale); t = CGAffineTransformTranslate(t, translateX, translateY); self.transform = t; - hpique
数字(c)无法工作,似乎中心点是相同的,转换需要一段时间才能生效吗? - htafoya
显示剩余5条评论

5

以下是我在 Swift5 中找到的保持坐标原点(0,0)不变的视图缩放方法:

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
}
}

感谢Hacking with Swift提供的内容。


4
首先 #import <QuartzCore/QuartzCore.h>,然后设置您的视图的锚点:
   [[self layer] setAnchorPoint:CGPointMake(0, 0)];

1
那将更改所有变换的锚点。我想创建一个具有特定锚点的比例变换。 - hpique
CGAffineTransform tr = CGAffineTransformScale(self.transform,2,2); self.transform = tr; self.center = CGPointMake(0,0); - Mudit Bajpai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接