以顶部中心为锚点来缩放UIView?

时间:2012-12-23 01:33:27

标签: objective-c uiview calayer

我正在使用CGAffineTransformMakeScale缩放UIView,但我希望将其固定在当前的顶部中心点,因为它已缩放。

我已着手设置view.layer.anchorPoint,但我相信我需要将此设置与设置view.layer.position一起使用,以解释定位点的变化。

如果有人能指出我正确的方向,我将非常感激!

4 个答案:

答案 0 :(得分:38)

请在此处查看我的答案,了解更改定位点后视图移动的原因:https://stackoverflow.com/a/12208587/77567

因此,请将视图的转换设置为标识。当视图未转换时,找到其上边缘的中心:

CGRect frame = view.frame;
CGPoint topCenter = CGPointMake(CGRectGetMidX(frame), CGRectGetMinY(frame));

然后锚点指向上边缘的中间:

view.layer.anchorPoint = CGPointMake(0.5, 0);

现在图层的position(或视图的center)是图层上边缘中心的位​​置。如果你停在此处,图层将移动,使其顶边的中心位于更改锚点之前的真实中心位置。因此,从刚才将图层的position更改为其上边缘的中心:

view.layer.position = topCenter;

现在图层停留在屏幕上的相同位置,但其锚点是其上边缘的中心,因此缩放和旋转将使该点固定。

答案 1 :(得分:2)

Swift 4.2

使用特定锚点缩放UIView,同时避免错位:

extension UIView {
    func applyTransform(withScale scale: CGFloat, anchorPoint: CGPoint) {
        layer.anchorPoint = anchorPoint
        let scale = scale != 0 ? scale : CGFloat.leastNonzeroMagnitude
        let xPadding = 1/scale * (anchorPoint.x - 0.5)*bounds.width
        let yPadding = 1/scale * (anchorPoint.y - 0.5)*bounds.height
        transform = CGAffineTransform(scaleX: scale, y: scale).translatedBy(x: xPadding, y: yPadding)
    }
}

因此,以顶部中心为锚点将视图缩小到一半大小:

view.applyTransform(withScale: 0.5, anchorPoint: CGPoint(x: 0.5, y: 0))

答案 2 :(得分:1)

这是一个老问题,但是我遇到了同样的问题并且花了我很多时间来达到理想的行为,从@Rob Mayoff那里扩展了一点答案(我找到了解决方案归功于他的说明)。 我必须从用户触摸的点显示浮动视图缩放。根据屏幕坐标,它可以缩小,向右,向左,向上或从中心向下缩放。

要做的第一件事是在触摸点设置浮动视图的中心(它必须是中心,'因为Rob解释):

-(void)onTouchInView:(CGPoint)theTouchPosition
{
self.floatingView.center = theTouchPosition;
....
}

下一个问题是设置图层的锚点,具体取决于我们想要做什么(我测量了相对于屏幕框架的点,并确定了将其缩放的位置):< / p>

switch (desiredScallingDirection) {
    case kScaleFromCenter:
    {
        //SCALE FROM THE CENTER, SO
        //SET ANCHOR POINT IN THE VIEW'S CENTER
        self.floatingView.layer.anchorPoint=CGPointMake(.5, .5);
    }
        break;
    case kScaleFromLeft:
        //SCALE FROM THE LEFT, SO
        //SET ANCHOR POINT IN THE VIEW'S LEFT-CENTER
        self.floatingView.layer.anchorPoint=CGPointMake(0, .5);
        break;
    case kScaleFromBottom:
        //SCALE FROM BOTTOM, SO
        //SET ANCHOR POINT IN THE VIEW'S CENTER-BOTTOM
        self.floatingView.layer.anchorPoint=CGPointMake(.5, 1);
        break;
    case kScaleFromRight:
        //SCALE FROM THE RIGHT, SO
        //SET ANCHOR POINT IN THE VIEW'S RIGHT-CENTER
        self.floatingView.layer.anchorPoint=CGPointMake(1, .5);
        break;
    case kScallingFromTop:
        //SCALE FROM TOP, SO
        //SET ANCHOR POINT IN THE VIEW'S CENTER-TOP
        self.floatingView.layer.anchorPoint=CGPointMake(.5, 0);
        break;
    default:
        break;

}

现在,一切都很简单。取决于您想要给动画的效果(想法是从0到100%的弹跳缩放):

//SETUP INITIAL SCALING TO (ALMOST) 0%
CGAffineTransform t=CGAffineTransformIdentity;
t=CGAffineTransformScale(t, .001, .001);
self.floatingView.transform=t;
[UIView animateWithDuration:.2
                      delay:0
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                     //BOUNCE A LITLE UP!
                     CGAffineTransform t = CGAffineTransformMakeScale(1.1,1.1);
                     self.floatingView.transform=t;
                 } completion:^(BOOL finished) {
                     [UIView animateWithDuration:.1
                                      animations:^{
                                          //JUST A LITTLE DOWN
                                          CGAffineTransform t = CGAffineTransformMakeScale(.9,.9);
                                          self.floatingView.transform = t;
                                      } completion:^(BOOL finished) {
                                          [UIView animateWithDuration:.05
                                                           animations:^{
                                                               //AND ALL SET
                                                               self.floatingView.transform  = CGAffineTransformIdentity;
                                                           }
                                           completion:^(BOOL finished) {
                                               //ALL SET
                                           }];
                     }];
                 }];

那就是它。正如您所看到的,主要是正确设置视图的位置和定位点。然后,它就是小菜一碟! 问候,并让代码与你同在!

答案 3 :(得分:1)

Swift 4.2

这对我有用:

public void stopRecording(){
        if (recordstarted) {
            recorder.stop();
            audioManager.setMode(AudioManager.MODE_NORMAL);
            recordstarted = false;
        }
    }