深入坐标系 和坐标系相关的四个属

来源:互联网 发布:百度语音识别 python 编辑:程序博客网 时间:2024/04/28 16:08

1. 深入坐标系

和坐标系相关的四个属性: .frame   .bounds  .transform  .center

1.1 .frame属性

1> 是什么

是一个CGRect类型的结构体{x, y, width,height}

描述了子视图在父视图中的位置(origin)及所占父视图空间的大小(size)

2> 什么时候使用.frame属性

当一个子视图在父视图中做以下事情时:

1) 初始化子视图的坐标和大小时,肯定是对子视图的.frame属性赋值

2) 在不使用transform/AutoLayout技术时, 修改坐标信息

3> .frame属性和其他三个的关系

1)一般情况下,如果一个视图的.transform是初始值时,视图的.frame和.bounds中的size值相同。

2)修改了.frame ---> .size ---> .bounds

修改.frame会导致.bounds联动

3) .frame --> .center

修改子视图的.frame属性,会导致子视图在父视图上的中心点发生变化(.center)

4)  .frame --> .transform

一个视图的.frame发生变化会导致.transform属性联动。所以,如果一个视图.transform属性被主动改变,那么其本身的.frame属性就不应该再主动修改。


1.2 .bounds属性

1> 是什么

是一个CGRect类型的结构体

描述的是一个视图自己的坐标系大小,和父视图无关。由于.bounds描述的是自身的宽和高,所以没有位置信息:

.origin (永远是0,0)

.size

2> 什么时候用

当计算子视图坐标需要参照父视图坐标系时,获取父视图的宽和高应该使用.bounds属性(读取值)


当写一个view的子类时(比如自定义Cell), 视图的大小不由外部决定, 而是由数据的多少决定,计算大小时,就需要自行修改视图(如Cell)的bounds(修改值)

3> 和其他三个的关系

1) .bounds --> .frame

2) .bounds --> .center

注意: .bounds并不会导致.transform的变化

1.3 .transform

1> 是什么

是一个CGAffineTransform的结构体

描述的是一个3x3的矩阵,此矩阵会让视图在.frame的基础上变形

2> 什么时候用

1) 视图处于自动布局(AutoLayout)的管理之下时,不可使用

2)只在需要让视图出现一些特效时(缩放、旋转、位移)使用

3> 和其他三者的关系

1) .transform  -->   .frame

变形之后,子视图所占的父视图的空间大小和位置会改变

2) .transform --> .center

3) 特别注意,.transform的改变不会导致.bounds的改变


1.4 .center

是一个视图的中央点所在的坐标

位移时用

.center --> .frame.origin

.center --> .bounds(不会)

.center --> .transform   (不会)


特别注意:

只有主动修改.frame的值时,.bounds的值才会跟随改变,但.transform的改变导致的.frame的变化,并不会导致.bounds的变化。


如果一个视图的.transform没有发生过任何变化,那么.frame和.bounds就一直保持一致,但是,当.transform发生变化时,.frame和.bounds就不再保持一致,除非.transform恢复到初始值。


2. 触控(Touch)

3.1 是什么

触控是用户接触屏幕后产生的对象, 其类型为UITouch

3.2 能干什么

视图中通过覆盖父类的一些方法获取触控对象,从而得知用户的Touch操作和动作轨迹等,以此可以进行绘图、涂鸦、手写等操作。

3.3 怎么用

在视图类中覆盖父类的方法:

touchesBegan:withEvent:

touchesMoved:withEvent:

touchesEnded:withEvent:

2. 手势

2.1 什么是手势

用户对view的进行的一些触屏操作, 

2.2 有哪些手势

一次性手势:

Tap :  点, 按

Swipe : 轻扫、滑动

连续性手势:

LongPress  :   长按

Pan     : 拖动

Pinch:   捏/拨/扩、缩放

Rotation     :   旋转

2.3 本质 

用户对视图的手势操作,会被封装成手势对象,告诉系统

一次手势形成后(系统对手势识别成功),只触发一次事件,调用一次方法

连续性手势形成后,会连续触发事件,会重复调用事件方法

2.4 如何使用

手势是对象,首先需要创建。

每一种手势都有一个类,这些类都继承自UIGestureRecognizer类, 子类一般命名为UIXxxGestureRecognizer,如:

UITapGestureRecognizer

UIPanGestureRecognizer

UISwipeGestureRecognizer

使用步骤:

1> 创建手势对象

2> 设置手势的相关属性

3> 将手势加入到需要响应手势的视图中

3. 具体手势案例

3.1 UITapGestureRecognizer

[Demo2]

重要属性:

numberOfTapsRequired

numberOfTouchesRequired

经常用来将任何View变成按钮


3.2 UISwipeGestureRecognizer

[Demo3]

numberOfTouchesRequired

direction

可以有多个方向,用"|"方式叠加

3.3 UILongPressGestureRecognizer

minimumPressDuration  短多少秒算长按

allowableMovement  允许移动的距离,超过这个距离就不能算长按了

3.4 UIPinchGestureRecognizer

[Demo4]

练习:

界面上有一个UITextView, 用来看小说,如果老板来了,快速pinch (捏), UITextView就看不见了, 老板走了,快速pinch(扩), 小说就又能看了。

如果捏或扩的速度不快,那就不是老板来了


3.5 UIPanGestureRecognizer

[Demo5]

minimumNumberOfTouches 最少几个手指


//获取当前手指在指定视图中的位置 

- (CGPoint)translationInView:(UIView *)view;

//获取当前手指在指定视图中移动的速度

   - (CGPoint)velocityInView:(UIView *)view;

.center


3.6 UIRotationGestureRecognizer

[Demo6]

.rotation

.velocity

3.7 手势状态

一个手势是有状态的,由属性.state来描述,有以下状态:

Began:  手势已经成功识别

Changed: 手势变化中(连续性手势) , 一次性手势没有此状态

Ended: 手势撤销(结束)



4. 变形

4.1 概念

让一个视图旋转、缩放、位移

任何一个视图对象都有一个属性叫.transform, 负责描述此view在父view中的坐标系的变化:

旋转(rotation)

绽放(scale)

位移(translation)

4.2 .transform的内部结构

.transform属性是什么类型: CGAffineTransform结构体, 结构体内部有6个成员+3个固定值, 形成一个3x3的矩阵, 这个矩阵中的6个值发生一些变化时,就会导致视图以生旋转、缩放、位移的效果。


4.3 如何使用

理论上,如果改变了view的.transform属性中的那6个值,就可以达到让view进行旋转、缩放、位移等效果。

但实际上,我们很难计算出这6值。我们会借助一些API来生成.transform属性,达到相同的效果。


4.4 变形和自动布局

变形和自动布局技术(Auto Layout)是有冲突的,所以,一般情况下,如果需要对视图进行变形,那么,应该关闭视图的自动布局功能。


4.5旋转变形(Rotation)


CGAffineTransformMakeRotation 创建一个transform,0位置开始


CGAffineTransformRotate 在原来旋转度的基础上再叠加

1> 取得原来的.transform

CGAffineTransform transform =self.earthImageView.transform;

2> 将现在的旋转度加到原来的上面,形成新的transform

transform =CGAffineTransformRotate(transform, gr.rotation);

3> 再赋值回去

self.earthImageView.transform = transform;

4> 如果用手势,一般需要将手势的rotation置成0, 以便继续旋转时叠加数值。

gr.rotation =0;


4.6 缩放变形(Scale)

[Demo6]

CGAffineTransformMakeScale(widthScale, heightScale); //直接创建一个缩放的transform

CGAffineTransformScale(transform, gr.scale, gr.scale);//原来的transform基础上叠加

叠加时需要注意,如果使用手势,每次手势的scale都在重置为1.0:   gr.scale = 1.0;


4.7 位移变形(translation)

[Demo6]

CGAffineTransformMakeTranslation  //直接创建

CGAffineTransformTranslate //用以前的基础创建

叠加时需要注意,如果使用手势,每次手势的translation都在重置为0  :[gr setTranslation:CGPointZeroinView:self.view];


注意: 对于位移,一般会直接修改view的.center属性来完成,基本不会使用.transform属性来做位移。


4.8CGAffineTransformIdentity

是一个系统定义好的常量, 是所有视图对象.transform属性的初始值。


0 0
原创粉丝点击