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

这个问题首先要清晰的知道,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)。下图更容易理解。

一、如何设置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到默认。

iOS围绕某点缩放或旋转的AnchorPoint的设定的更多相关文章

  1. View的平移、缩放、旋转以及位置、坐标系

    原创 2015年05月12日 13:15:29 标签: Android / Scroll / Scale / Translation / Rotation 24733 Android开发中,经常会接触 ...

  2. iOS--------手势识别的详细使用:拖动、缩放、旋转、点击、手势依赖、自定义手势

    1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了 ...

  3. OpenCV2:图像的几何变换,平移、镜像、缩放、旋转(2)

    在OpenCV2:图像的几何变换,平移.镜像.缩放.旋转(1)主要介绍了图像变换中的向前映射.向后映射.处理变换过程中浮点坐标像素值的插值算法,并且基于OpenCV2实现了两个简单的几何变换:平移和镜 ...

  4. OpenCV2:图像的几何变换,平移、镜像、缩放、旋转(1)

    图像的几何变换是在不改变图像内容的前提下对图像像素的进行空间几何变换,主要包括了图像的平移变换.镜像变换.缩放和旋转等.本文首先介绍了图像几何变换的一些基本概念,然后再OpenCV2下实现了图像的平移 ...

  5. Android动画及图片的缩放和旋转

    Android动画有2种,一种是Tween Animation,另一种是Frame Animation,先说说Tween动画吧. Tween动画是对视图对象中的内容进行一系列简单的转换,比如位置的移动 ...

  6. OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图

    读取bmp等图片格式中的像素还有难度,就先用这个棋盘图象素来弄了 代码打错一个就一直First-chance exception ,貌似还有一个要用q或者Q才能成功退出,不知道缺少哪句,我用窗口红叉退 ...

  7. js手写图片查看器(图片的缩放、旋转、拖拽)

    在做一次代码编辑任务中,要查看图片器.在时间允许的条件下,放弃了已经封装好的图片jq插件,现在自己手写js实现图片的缩放.旋转.推拽功能! 具体代码如下: <!DOCTYPE html> ...

  8. Three.js 保存camera(视角)设置到数据库,包括场景的缩放、旋转、移动等

    最近在做的项目中遇到需要保存当前的3d管道视角设置的问题,用户希望在对3d场景内的管道进行了缩放.旋转.移动之后可以将场景当前的视角状态保存在数据库中,并在下次加载时读取. 经过不断的尝试和研究,在同 ...

  9. java处理图片--图片的缩放,旋转和马赛克化

    这是我自己结合网上的一些资料封装的java图片处理类,支持图片的缩放,旋转,马赛克化.(转载请注明出处:http://blog.csdn.net/u012116457) 不多说,上代码: packag ...

随机推荐

  1. PolarDB阿里初赛问题记录 PolarDB 阿里 中间件 比赛 性能 工程手册

    Contents 这篇纯碎是碎碎念记录. 每个value都是4KB,总共最多会写6400W个value,算下来就是64 * 1000 * 1000 * 4 * 1024 Bytes ≈ 256G. 每 ...

  2. @EnableGlobalMethodSecurity(prePostEnabled = true)

    http://www.bubuko.com/infodetail-2243816.html

  3. Linux基础常用命令大全学习

    1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...

  4. sqlserver 命令执行sql脚本

    osql -S 主机名 -U 用户名 -P 密码 -i E:\20190723.sql

  5. springboot学习笔记:11.springboot+shiro+mysql+mybatis(通用mapper)+freemarker+ztree+layui实现通用的java后台管理系统(权限管理+用户管理+菜单管理)

    一.前言 经过前10篇文章,我们已经可以快速搭建一个springboot的web项目: 今天,我们在上一节基础上继续集成shiro框架,实现一个可以通用的后台管理系统:包括用户管理,角色管理,菜单管理 ...

  6. Invalid action class configuration that references an unknown class解决方案

    Sturts2整合后时出现诡异的异常: java.lang.RuntimeException: Invalid action class configuration that references a ...

  7. [LC] 215. Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  8. springdatajpa 认识以及使用方式

    1.spingdatajpa是什么? Spring Data JPA 是 Spring 基于 ORM 框架.JPA 规范的基础上封装的一套JPA应用框架(即上述的:JPA的实现产品),可使开发者用极简 ...

  9. JVM笔记(二)

    内存分配1)对象的内存分配,往大的方向讲,就是在堆上分配2)对象优先在Eden分3)大对象直接进入老年代4)长期存活的对象进入老年代:对象在Survivor区每“熬过”一次Minor GC,年数加1, ...

  10. Luogu_2878_[USACO07JAN]保护花朵Protecting the Flowers

    题目描述 Farmer John went to cut some wood and left N (2 ≤ N ≤ 100,000) cows eating the grass, as usual. ...