前一篇知道改变一个视图的位置有两种方法。
- 修改自己的
frame
2.修改SuperView
的bounds
的origin
- 其实
frame
是一个计算出来的值,属于一个抽象概念,间接影响视图的布局。
frame.origin.x = position.x - bounds.size.width * anchorPoint.x
frame.origin.y = position.y - bounds.size.height * anchorPoint.y
- 真正能确定一个视图位置的参数是
Position
和bounds
以及archor point
三者联合定位的结果,Position
确定起始点archor point
确定长宽扩展方向,bounds
的size
确定视图的长宽。
矢量是有方向的,
Position
变量代表一个点,anchor point
代表位置方向。anchor point
有九种位置,如图
由①②③④⑤⑥⑦⑧⑨分别表示九个点,
中间
(视图默认值Center)
示例
目前以①③⑤⑦⑨为例,看Demo
默认archor point
在中间
代码
_nomalLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 200, 100, 100)];
_nomalLabel.backgroundColor = [UIColor yellowColor];
_nomalLabel.textAlignment = NSTextAlignmentCenter;
_nomalLabel.text = @"Center";
[self.view addSubview:_nomalLabel];
视图
说明
Position
位置(150,150),bounds
的size
(100,100),archor point
(0.5,0.5)在中间,代表从Position
位置向外延伸各50point.
archor point
在左上
代码
_leftTopLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 200, 100, 100)];
_leftTopLabel.layer.anchorPoint = CGPointMake(0, 0);
UIColor *color1 = [UIColor redColor];
color1 = [color1 colorWithAlphaComponent:0.3];
_leftTopLabel.backgroundColor = color1;
_leftTopLabel.textAlignment = NSTextAlignmentCenter;
_leftTopLabel.text = @"LeftTop";
[self.view addSubview:_leftTopLabel];
视图
说明
Position
不变,Position
是基于Super View
的坐标系的,Bounds
不变Size
也不变,archor point
变为左上
,代表position
在视图的左上位置
,也即是如图所示了。
旋转之后的点击区域
问题
如图
有一个view,原始位置是红色区域,进行旋转45度之后为绿色区域,蓝色区域为view的
frame
大小。问题:如果给旋转后的view添加
UITapGestureRecognizer
事件,在那个区域是响应区域?答案是绿色区域,其他任何地方都无法响应。
分析
这个涉及到两个地方
-
frame
在视图设置了transform
(平移、缩放、旋转)之后,值无效,无法正确反应视图的位置信息。 -
hit-testing
问题,在pointInside:withEvent:
的返回时候,如何判断一个点击点是否在本视图里。关于这块文档在这里
坐标系
用户空间
apple doc
这个涉及到绘制原理,本App
把当前windows
的所有子Layer
的信息封装一个个命令,发送到另一个系统绘图服务器,这一个个命令是基于当前的坐标系的,基准点是Point
设备空间
同样,这些命令发送到系统绘图服务器,系统服务器把这些point
用像素点映射到屏幕上,用户就看到了图像。设备空间可能是一个屏幕,一个打印机等等。
CTM
CTM是矩阵的缩写,用来对坐标系进行操作从而实现视图的平移,旋转,缩放等。缩放旋转这些操作都是基于position
以及anchor point
。position
和anchor point
结合起来,像一颗图钉一样,固定一个具体的位置。