前一篇知道改变一个视图的位置有两种方法。
- 修改自己的
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有九种位置,如图

未命名_7_rtf.png

1483066424066.png
由①②③④⑤⑥⑦⑧⑨分别表示九个点,
中间(视图默认值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];
视图

截屏2016_12_30_上午11_28.png
说明
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];
视图

截屏2017_1_3_下午5_21.png
说明
Position不变,Position是基于Super View的坐标系的,Bounds不变Size也不变,archor point变为左上,代表position在视图的左上位置,也即是如图所示了。
旋转之后的点击区域
问题
如图

截屏2017_1_3_下午5_52.png
有一个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结合起来,像一颗图钉一样,固定一个具体的位置。