(比例)在一个点上放大UIView

20

我不理解关于变换的某些事情。我想要放大UIView(主视图)的右上角。我使用了CGAffineTransformScale并尝试设置中心/锚点以及CGAffineTransformMakeTranslation,但都没有成功。

我无法弄清楚如何正确设置平移,以便它会在这个点上缩放。

CGAffineTransform tr = CGAffineTransformScale(self.view.transform, 2, 2);

[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
            self.view.transform = tr;
            self.view.center = CGPointMake(480,0);

} completion:^(BOOL finished) {}];

缩放到任意点怎么样?例如,响应用户点击屏幕时? - user978838
2个回答

35

你正在将视图的中心设置为右上角。这意味着你正在放大某个位于中心左下方的地方。

尝试这个

CGAffineTransform tr = CGAffineTransformScale(self.view.transform, 2, 2);
CGFloat h = self.view.frame.size.height;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
    self.view.transform = tr;
    self.view.center = CGPointMake(0,h);
} completion:^(BOOL finished) {}];

这将把放大视图的中心设置为左下角,有效地以固定右上角的方式进行缩放。

这段代码没有硬编码高度,这使得它更具可移植性(适用于iPad或iPhone 5)。

在设置transform属性之前,您需要先保存h,因为此后便不能依赖于frame的值。

编辑

要使其适用于任何比例s,请使用以下代码:

CGFloat s = 3;
CGAffineTransform tr = CGAffineTransformScale(self.view.transform, s, s);
CGFloat h = self.view.frame.size.height;
CGFloat w = self.view.frame.size.width;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
    self.view.transform = tr;
    self.view.center = CGPointMake(w-w*s/2,h*s/2);
} completion:^(BOOL finished) {}];

要使其适用于左下方,请使用以下内容:

CGFloat s = 3;
CGAffineTransform tr = CGAffineTransformScale(self.view.transform, s, s);
CGFloat h = self.view.frame.size.height;
CGFloat w = self.view.frame.size.width;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
    self.view.transform = tr;
    self.view.center = CGPointMake(w*s/2,h-h*s/2);
} completion:^(BOOL finished) {}];
要使其适用于右下角,请使用此代码:
CGFloat s = 3;
CGAffineTransform tr = CGAffineTransformScale(self.view.transform, s, s);
CGFloat h = self.view.frame.size.height;
CGFloat w = self.view.frame.size.width;
[UIView animateWithDuration:2.5 delay:0 options:0 animations:^{
    self.view.transform = tr;
    self.view.center = CGPointMake(w-w*s/2,h-h*s/2);
} completion:^(BOOL finished) {}];

参见:如何缩放(缩小)UIView到给定的CGPoint


谢谢,这对我来说可以直接使用,但在大于3的比例尺下会更加向实际中心缩放。如果是针对右下角,该怎么做呢?奇怪的是,这对我来说有效:self.view.center = CGPointMake(-280,-h)。 - akaru
1
这是正确的,因为放大视图的中心取决于比例尺。我添加了右下/左下和任意比例尺的示例。只需记住:首先放大视图(使其变成320s,480s大小),然后设置该视图的中心。 - mvds
太棒了!那就是我所缺少的简单的小算法,谢谢你。如果我想要轻松恢复,使用MakeTranslate是否比设置中心更好呢? - akaru
这是一段非常棒的小代码。你应该写博客分享它 ;) - Eric Brotto
2
这可能超出了问题的范围,但您如何修改它以适应视图中的任意CGPoint? - glenstorey
非常好用。在完成时,我最终添加了 self.view.transform = .identity 来恢复几个子视图的扭曲。 - byJeevan

3

如果还有人感兴趣的话,这里是Swift 3.0的解决方案,我添加了正确淡出的可能性。

(我知道有两个枚举类型缺失,但代码仍然可读,我认为你会理解概念)

func animateZoom(direction: ZoomDirection, type: ZoomType, duration: Double = 0.3, scale: CGFloat = 1.4) {
    var cx, cy: CGFloat
    var tr: CGAffineTransform = CGAffineTransform.identity

    if (type == .IN) { tr = self.transform.scaledBy(x: scale, y: scale) }

    let h: CGFloat = self.frame.size.height;
    let w: CGFloat = self.frame.size.width;

    if (type == .IN) {
        switch direction {
        case .LEFT_DOWN:
            cx = w*scale/2
            cy = h-h*scale/2
            break
        case .LEFT_UP:
            cx = w*scale/2
            cy = h*scale/2
            break
        case .RIGHT_UP:
            cx = w-w*scale/2
            cy = h*scale/2
            break
        case .RIGHT_DOWN:
            cx = w-w*scale/2
            cy = h-h*scale/2
            break
        }
    } else {
        cx = w/scale/2
        cy = h/scale/2
    }

    UIView.animate(withDuration: duration, delay: 0, options: [.curveEaseInOut], animations: {
        self.transform = tr
        self.center = CGPoint(x: cx, y: cy)
    }, completion: { finish in })
}

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