【问题标题】:Scale with CGAffineTransform and set the anchor使用 CGAffineTransform 缩放并设置锚点
【发布时间】:2012-02-04 04:03:54
【问题描述】:

如果我理解正确缩放 UIViewCGAffineTransform 将转换锚定到其中心。

特别是:

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

如何创建使用特定锚点(例如 0;0)的 CGAffineTransform 比例?

【问题讨论】:

  • 这很奇怪,我在 iOS 7 上,它不会从中心缩放,而是从左上角缩放...即使我将锚点设置为 (0.5, 0.5) 它也不会不要从中心缩放。有人有想法吗?
  • @VanDuTran 我发现在视图的layer 上使用CATransform3D 行为正确并遵守anchorPoint。尝试使用 CGAffineTransformMakeScale,而不是使用 CGAffineTransformMakeScale,它会以某种方式将视图限制在窗口顶部和左侧边界。
  • @JonathanLin 我使用带有 CATransform3D 的图层,这在 iOS 7 上也没有运气

标签: iphone ios scaling cgaffinetransform


【解决方案1】:

这是我在 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

【讨论】:

    【解决方案2】:

    首先#import <QuartzCore/QuartzCore.h>,然后设置视图的锚点:

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

    【讨论】:

    • 这将改变所有转换的锚点。我想创建一个带有特定锚点的比例变换。
    • CGAffineTransform tr = CGAffineTransformScale(self.transform, 2, 2); self.transform = tr; self.center = CGPointMake(0,0);
    【解决方案3】:

    (a)

    缩放然后平移?

    类似:

    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;
    

    【讨论】:

    • 方法 (a) 以 2 的比例打印 50;50;200;200。将很快测试方法 (b),但这不会影响所有转换吗?可能会引起副作用。
    • 那是因为第一个比例变换会影响第二个。您应用转换的顺序很重要;)如果这只是您尝试进行的翻译,那么我不只是将框架/边界/中心设置为新位置吗?
    • 不要忘记,如果您向上平移 100 像素,但您的变换的比例已经为 2,那么您实际上是向上平移了 200 像素 - 当您决定要平移多远时,您必须补偿您的比例因子翻译!
    • 看看这篇文章:iphonedevelopment.blogspot.com/2008/10/… - 我发现它很有帮助!
    • 经过几次测试后,看起来 (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;
    猜你喜欢
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2016-12-13
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多