zoukankan      html  css  js  c++  java
  • iOS围绕某点缩放或旋转的AnchorPoint的设定

    经常会遇到需求,要求手势的缩放或者旋转操作,要求动作变化围绕某一个特定点,或者是两指的中心点,或者是某一个点。

    这个问题首先要清晰的知道,iOS各个view的层次关系。特别是,要清除的知道,当前view的frame与superView的bounds是一个坐标系。

    具体来讲,AnchorPoint 是iOS CoreAnimation层的事物。图层的anchorPoint属性是一个CGPoint值,它指定了一个基于图层bounds的符合位置坐标系的位置。Anchor point指定了bounds相对于position的值,更重要的是,它是变换的支点。AnchorPoint值的范围是0 – 1 ,可以理解为AnchorPoint表示了支点位置的坐标占bounds的比例。

    iOS CoreAnimation 坐标系原点位于左上角,因此,我们可以很容易的知道,如果想要一个图层的支点位于图层左上角,那么它的AnchorPoint应该是(0, 0)。相应的如果想要支点位于左下角,AnchorPoint应该是 (0, 1)。而默认的中心点的AnchorPoint是(0.5, 0.5)。下图更容易理解。

    Snip20140108_2

    一、如何设置AnchorPoint?

    事实上,如果更改了一个图层的AnchorPoint,那么这个图层会发送位移。原因不表,看看文档便知。问题是发生位移之后,我们怎么将位移修复回来。下面是写的方法。

    - (void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
    {
        CGPoint oldOrigin = view.frame.origin;
        view.layer.anchorPoint = anchorPoint;
        CGPoint newOrigin = view.frame.origin;
    
        CGPoint transition;
        transition.x = newOrigin.x - oldOrigin.x;
        transition.y = newOrigin.y - oldOrigin.y;
    
        view.center = CGPointMake (view.center.x - transition.x, view.center.y - transition.y);
    }

    当然你也可以把他写进UIView 的 categary。调用就更方便了。

    在进行完围绕AnchorPoint的变换之后,一定要切记将AnchorPoint改回默认。否则有些不需要特殊AnchorPoint的操作,比如拖动,就会变得乱七八糟了。

    - (void)setDefaultAnchorPoint forView:(UIView *)view
    {
        [self setAnchorPoint:CGPointMake(0.5f, 0.5f) forView:view];
    }

    OK,以上是我们在知道了AnchorPoint之后,怎么进行AnchorPoint的设置和回归。那么怎么得到我们真正想要的AnchorPoint的值呢?

    二、如何获得AnchorPoint?

    如果是两指的缩放或者旋转,有以下方法供参考:

    /**
     *  Correct  UIGestureRecognizer 's view 's anchor point , make the view scale or rotate correctly.
     */
    - (void)correctAnchorPointBaseOnGestureRecognizer:(UIGestureRecognizer *)gr
    {
        CGPoint onoPoint = [gr locationOfTouch:0 inView:gr.view];
        CGPoint twoPoint = [gr locationOfTouch:1 inView:gr.view];
    
        CGPoint anchorPoint;
        anchorPoint.x = (onoPoint.x + twoPoint.x) / 2 / gr.view.bounds.size.width;
        anchorPoint.y = (onoPoint.y + twoPoint.y) / 2 / gr.view.bounds.size.height;
    
        [self setAnchorPoint:anchorPoint forView:gr.view];
    }

    记得在UIGestureRecongizer 里,当state == UIGestureRecognizerStateBegan 时,进行调用。然后在手势结束或者失败的时候,(Gr.state == UIGestureRecognizerStateEnded || Gr.state == UIGestureRecognizerStateFailed || pinchGr.state == UIGestureRecognizerStateCancelled) ,将Anchor Point回归默认。

    如果是比如我需求里所需,要求90度旋转的时候,围绕画布中心而不是视图中心旋转。有如下方法参考

    - (void)correctAnchorPointForView:(UIView *)view
    {
        CGPoint anchorPoint = CGPointZero;
        CGPoint superviewCenter = view.superview.center;
    //   superviewCenter是view的superview 的 center 在view.superview.superview中的坐标。
        CGPoint viewPoint = [view convertPoint:superviewCenter fromView:view.superview.superview];
    //   转换坐标,得到superviewCenter 在 view中的坐标
        anchorPoint.x = (viewPoint.x) / view.bounds.size.width;
        anchorPoint.y = (viewPoint.y) / view.bounds.size.height;
    
        [self setAnchorPoint:anchorPoint forView:view];
    }

    同样记得,变换完毕后,重置 AnchorPoint到默认。

  • 相关阅读:
    14 Longest Common Prefix
    11. Container With Most Water
    9. Palindrome Number
    8. String to Integer (atoi)
    7. Reverse Integer
    5. Longest Palindromic Substring
    4. Median of Two Sorted Arrays
    tableViewCell中添加webView,cell自适应webView高度,解决死循环的简单办法
    ASIHTTPRequest实现断点下载
    如何在iOS中使用Block
  • 原文地址:https://www.cnblogs.com/mgbert/p/3874766.html
Copyright © 2011-2022 走看看