View Geometry and Coordinate Systems
二、视图几何和坐标系统
The default coordinate system in UIKit has its origin inthe top-left corner and has axes that extend down and to the right from theorigin point. Coordinate values are represented using floating-point numbers,which allow for precise layout and positioning of content regardless of theunderlying screen resolution.Figure 1-4showsthis coordinate system relative to the screen. In addition to the screencoordinate system, windows and views define their own local coordinate systemsthat allow you to specify coordinates relative to the view or window origininstead of relative to the screen.
UIKit框架的默认坐标系统的原点是在左上角,并有从原点开始向下和向右延伸的坐标轴。坐标值由浮点数字表示,它被用于精确的布局和内容的定位,而不需管底层屏幕的分辨率。图1-4显示了相对于屏幕的该坐标系统。除了屏幕坐标系统,窗口和视图还定义了它们自己的局部坐标系统,用来让你指定坐标,该坐标相对于视图或窗口原点的,而不是相对于屏幕的坐标。
Figure 1-4Coordinatesystem orientation in UIKit
图1-4 UIKit框架的坐标系方向。
Because every view and window defines its own localcoordinate system, you need to be aware of which coordinate system is in effectat any given time. Every time you draw into a view or change its geometry,you do so relative to some coordinate system.In thecase of drawing, you specify coordinates relative to the view’s own coordinatesystem. In the case of geometry changes, you specify coordinates relative tothe superview’s coordinate system. TheUIWindowandUIViewclasses both include methods to help you convert from one coordinatesystem to another.
因为每个视图和窗口都定义了自己的局部坐标系统,你需要在任何给定的时间都知道是哪个坐标系统在起作用。每次当你在一个视图里绘制或改变它的几何外形时,你都将根据一些坐标系统来做定位。在绘图时,你指定跟视图本身的坐标系统相关的坐标。在几何外形发生变化时,你指定跟父视图的坐标系统有关的坐标。UIWindow和UIView类都包含了各种帮助你转换坐标系统的方法。
重要:一些iOS技术定义了默认坐标系统,它们的原点和坐标轴方向都跟UIKit框架的不同。比如,Core Graphics和OpenGL ES的坐标系统原点位于视图或窗口的左下角,y轴上的点相对于屏幕向上。你的代码在绘图或创建内容时必须考虑到(take into account)这些差异,并根据需要调整坐标值(或坐标系统的默认方向)。
TheRelationship of the Frame, Bounds, and Center Properties
1.Frame, Bounds, Center属性之间的关系
A view object tracks its size and location using itsframe,bounds, andcenterproperties:
一个视图对象跟踪它的大小和位置使用它的frame,bounds,和center属性
·Theframepropertycontains the frame rectangle, which specifies the size and location of theview in its superview’s coordinate system.
frame属性包含了框架矩形,它指定了视图在父视图坐标系统中的的尺寸和位置。
·Theboundspropertycontains the bounds rectangle, which specifies the size of the view (andits content origin) in the view’s own local coordinate system.
bounds属性包含了边界矩形,它指定了视图在它自己的坐标系统中的的尺寸(以及它的初始内容)。
·Thecenterpropertycontains the known center point of the view in the superview’s coordinatesystem.
center属性包含了已知的视图中心点,该中心点以父视图坐标系统为参考。
You use thecenterandframeproperties primarily for manipulating the geometry of the current view. For example, you use these properties when building your view hierarchy or changing the position or size of a view at runtime. If you are changing only the position of the view (and not its size), thecenterproperty is the preferred way to do so. The value in thecenterproperty is always valid, even if scaling or rotation factors have been added to the view’s transform. The same is not true for the value in theframeproperty,which is considered invalid if the view’s transform is not equal to theidentity transform.
你主要使用center和frame属性来操纵当前视图的几何外形。比如,当你建立视图层次或在运行时改变视图的位置或尺寸时使用它们。如果你只改变视图的位置(而不改变它的尺寸),则center属性是最好的选择。center属性里的值一直是有效的,即使缩放或旋转因子已经被添加到视图的变换(transform)里。同样,frame属性里的值则不正确,因为该值在视图的变换不是恒等变换的,所以被认为无效。
You use theboundsproperty primarily during drawing. The bounds rectangle isexpressed in the view’s own local coordinate system. The default origin of thisrectangle is (0, 0) and its size matches the size of the frame rectangle.Anything you draw inside this rectangle is part of the view’s visible content.If you change the origin of the bounds rectangle, anything you draw inside thenew rectangle becomes part of the view’s visible content.
在绘图时,你主要使用bounds属性。边界矩形在视图自己的局部坐标系统里表示。该矩形的默认原点为(0,0),并且它的大小跟框架矩形的大小一致。任何在该矩形里绘制的东西都是视图可见内容的一部分。如果你改变了边界矩形的原点,任何你在新矩形里绘制的内容就成为视图可见内容的一部分。
Figure 1-5shows the relationship between the frame and bounds rectanglesfor an image view. In the figure, the upper-left corner of the image view islocated at the point (40, 40) in its superview’s coordinate system and the sizeof the rectangle is 240 by 380 points. For the bounds rectangle, the originpoint is (0, 0) and the size of the rectangle is similarly 240 by 380 points.
图1-5显示了一个图像视图的框架矩形和边界矩形之间的关系。在图中,图片视图的左上角坐标在它的父视图坐标系里是点(40,40),图片的尺寸是240x380点。对于边界矩形来说,原点是(0,0),矩形大小也是240x380点。
Figure 1-5Relationshipbetween a view's frame and bounds
图1-5视图框架和边框之间的关系
Although you can change theframe,bounds, andcenterproperties independent ofthe others, changes to one property affect the others in the following ways:
尽管你可以独立的改变frame, bounds,和center等属性,但是如果你改变了其中一个属性将对其它属性造成以下方面的影响:
·When you set theframeproperty, the size value in theboundsproperty changes to match the new size of the frame rectangle. The value in thecenterproperty similarlychanges to match the new center point of the frame rectangle.
当你设置frame属性时,bounds属性里的尺寸值将发生变化以匹配框架矩形的新尺寸。center属性的值同样被改变以匹配框架矩形的新中心点。
·When you set thecenterproperty, the origin value in theframechanges accordingly.
当你设置center属性时,frame里的原点值也相应的发生改变。
·When you set the size of theboundsproperty, the size value in theframeproperty changes to match the new size of the boundsrectangle.
当你设置bounds属性尺寸时,frame属性里的尺寸也发生改变以匹配边界矩形的新尺寸。
By default, a view’s frame is not clipped to itssuperview’s frame. Thus, any subviews that lie outside of their superview’sframe are rendered in their entirety. You can change this behavior, though, bysetting the superview’sclipsToBoundsproperty toYES. Regardless of whether or notsubviews are clipped visually, touch events always respect the bounds rectangleof the target view’s superview. In other words, touch events occurring in apart of a view that lies outside of its superview’s bounds rectangle are notdelivered to that view.
默认情况下,视图的框架不会按它的父视图框架进行裁剪。因此,任何超出它们父视图框架的子视图将作为一个整体(in their entirety)被渲染。但是,你可以通过把父视图的clipsToBounds属性设置为YES来改变该行为。不管视觉上子视图是否被裁减,视图永远只响应它的父视图范围内的触摸事件。换句话说,在父视图边界矩形外发生的触摸事件是不会被传递到该视图的。
CoordinateSystem Transformations
2.坐标系转换
Coordinate system transformations offer a way to alter yourview (or its contents) quickly and easily. An affine transform is amathematical matrix that specifies how points in one coordinate system map topoints in a different coordinate system. You can apply affine transforms toyour entire view to change the size, location, or orientation of the view relativeto its superview. You can also use affine transforms in your drawing code toperform the same types of manipulations to individual pieces of renderedcontent. How you apply the affine transform therefore depends on context:
坐标系转换让你快速简单的变换视图(或内容)。仿射变换(affine transform)是一种数学矩阵,它指定一个坐标系里的点如何对应于一个不同坐标系里的点。你可以在整个视图里应用仿射变换来改变尺寸,位置或与它父视图相关的视图的方向。你还可以在你的绘图代码里应用仿射变换来对渲染内容的各个独立块做同样类型的操作。根据上下文(context)来决定如何应用仿射变换:
·To modify your entire view,modify the affine transform in thetransformpropertyof your view.
修改整个视图,修改视图的transform属性中的仿射变换。
·To modify specific pieces ofcontent in your view’sdrawRect:method,modify the affine transform associated with the active graphics context.
在视图drawRect:方法中修改特定内容块,修改跟活动图形上下文(active graphics context)相关联的仿射变换。
You typically modify thetransformproperty of a viewwhen you want to implement animations. For example, you could use this propertyto create an animation of your view rotating around its center point. You wouldnot use this property to make permanent changes to your view, such as modifyingits position or size a view within its superview’s coordinate space. For thattype of change, you should modify the frame rectangle of your view instead.
当你想实现动画时,你通常会修改视图的transform属性。比如,你可以使用该属性来创建一个让视图围绕它的中心点旋转的动画。你可能不会使用该值来做视图的永久变化,比如修改视图在其父视图的坐标系里的位置或尺寸。对于那些变化,你应该用修改视图的框架矩形来替代。
Note: When modifying thetransformproperty of your view, all transformations are performedrelative to the center point of the view.
注意:当你修改视图的transform属性时,所有的变换都是相对于视图的中心点来执行的。
In your view’sdrawRect:method, you use affine transforms to position and orient theitems you plan to draw. Rather than fix the position of an object at somelocation in your view, it is simpler to create each object relative to a fixedpoint, typically (0, 0), and use a transform to position the object immediatelyprior to drawing. That way, if the position of the object changes in your view,all you have to do is modify the transform, which is much faster and lessexpensive than recreating the object at its new location. You can retrieve theaffine transform associated with a graphics context using theCGContextGetCTMfunctionand you can use the related Core Graphics functions to set or modify thistransform during drawing.
在视图的drawRect:方法中,你可以使用仿射变换来给你想要绘画的内容做定位和定方向。与其在视图里对一个对象做不同位置的定位,不如根据一个固定点(通常是(0,0))来创建每个对象,并紧接着在绘图时使用变换(transform)来做对象定位,这样做更加容易。那样,如果视图中的对象位置发生了改变,你只需要修改transform,这样比在新位置重新创建对象更快更省消耗。你可以用CGContextGetCTM函数来恢复跟一个图形上下文(graphics context)相关联的仿射变换,而且你可以在绘图期间使用相关的内核图形函数来设置或修改该transform.
The current transformation matrix (CTM) is theaffine transform in use at any given time. When manipulating the geometry ofyour entire view, the CTM is the affine transform stored in your view’stransformproperty.Inside yourdrawRect:method, the CTM is the affine transform associated with theactive graphics context.
当前变换矩阵(CTM)是在任何给定时间内使用的仿射变换。当操纵整个视图的几何外观时,CTM是存储在视图的transform属性里的仿射变换。在drawRect:方法里,CTM是跟活动图形上下文相关联的仿射变换。
The coordinate system of each subview builds upon the coordinate systems of its ancestors. So when you modify a view’stransformproperty, that changeaffects the view and all of its subviews. However, these changes affect onlythe final rendering of the views on the screen. Because each view draws itscontent and lays out its subviews relative to its own bounds, it can ignore itssuperview’s transform during drawing and layout.
每个子视图的坐标系都建立在它先祖的坐标系基础上。所以当你修改一个视图的transform属性时,该改变会影响视图及它的所有子视图。然而,这些改变只影响最终呈现在屏幕上的视图渲染。因为每个视图绘制它的内容并根据它自己的边界布局它的子视图,所以它在绘图和布局期间能忽略它父视图的变换(transform)。
Figure 1-6demonstrates how two different rotation factors combine
visually when rendered. Inside the view’sdrawRect:method, applying a 45 degree rotation factor to a shape causes thatshape to appear rotated by 45 degrees. Applying a separate 45 degree rotationfactor to the view then causes the shape to appear to be rotated by 90 degrees.The shape is still rotated by only 45 degrees relative to the view that drewit, but the view rotation makes it appear to be rotated by more.
图1-6演示了视觉上两个不同旋转因子在渲染时是如何被合并的。在视图的drawRect:方法,给一个形状应用一个旋转45度角的旋转因子,让形状旋转45度。然后给视图应用一个单独的45度角旋转因子,图形看起来就像被旋转了90度。而实际上图形相对于绘制它的视图来说任然只旋转了45度,但是视图的旋转让它看起来旋转了更多。
Figure 1-6Rotatinga view and its content
图1-6旋转视图及它的内容
Important: If aview’s transform property is not the identity transform, the value ofthat view’s frame property is undefined and must be ignored. Whenapplying transforms to a view, you must use theview’s bounds and center properties to get the size and positionof the view. The frame rectangles of any subviews are still valid because theyare relative to the view’s bounds.
重要:如果一个视图的transform属性不是恒等变换(identity transform),视图的frame属性值就是未定义并必须被忽视。当你给视图应用变换时,你必须使用视图的bounds和center属性来获取视图的尺寸和位置。任何子视图的框架矩形任然有效,因为它们是相对于视图的边界的。
For information about modifying your view’stransform property at runtime, see“Translating, Scaling, and Rotating Views.”For information about how to use transforms toposition content during drawing, seeDrawing and Printing Guide for iOS.
关于在运行时修改视图变换属性的更多信息,请看“Translating, Scaling, and Rotating Views.”关于在绘图时如何使用变换来定位内容的信息,请看Drawing and Printing Guide for iOS.
Points Versus Pixels
3.点与像素
In iOS, all coordinate values and distancesare specified using floating-point values in units referred to as points.The measurable size of a point varies from device to device and is largelyirrelevant. The main thing to understand about points is that they provide afixed frame of reference for drawing.
在iOS,所有的坐标值和距离使用浮点值指定单位,被称为点。一个点的可测量的大小因设备而异,在很大程度上是无关紧要的。理解点的主要原因是它们给绘图提供了一个固定的参考框架。
Table 1-1 lists the screen dimensions(measured in points) for different types of iOS-based devices in a portraitorientation. The width dimension is listed first, followed by the heightdimension of the screen. As long as you design your interface to these screensizes, your views will display correctly on the corresponding type of device.
表1-1列出了不同类型设备在垂直方向上的屏幕尺寸(按点衡量),这些尺寸都基于iOS。屏幕的宽尺寸在前,高尺寸在后。只要根据这些屏幕尺寸设计,视图将在相关类型的设备上正确显示。
Table 1-1 Screen dimensions for iOS-based devices
The point-based measuring system used foreach type of device defines what is known as the user coordinate space.This is the standard coordinate space you use for nearly all of your code. Forexample, you use points and the user coordinate space when manipulating thegeometry of a view or calling Core Graphics functions to draw the contents ofyour view. Although coordinates in the user coordinate space sometimes mapdirectly to the pixels on the device’s screen, you should never assume thatthis is the case. Instead, you should always remember the following:
每种类型的设备使用的基于点的测量系统定义了所谓的用户坐标空间。几乎所有代码都使用该标准坐标空间。比如,当你操纵视图的几何外形或调用内核图形函数来绘制视图的内容时,你将使用点和用户坐标空间。尽管用户坐标空间里的坐标有时直接跟设备屏幕上的像素相对应,但你绝不要认为它们就是同一种东西,你应用总是记住以下一点:
One point does not necessarily correspond to one pixel on the screen.
一个点并不一定对应于屏幕上的一个像素。
At the device level, all coordinates youspecify in your view must be converted to pixels at some point. However, themapping of points in the user coordinate space to pixels in the devicecoordinate space is normally handled by the system. Both UIKit and CoreGraphics use a primarily vector-based drawing model where all coordinate valuesare specified using points. Thus, if you draw a curve using Core Graphics, youspecify the curve using the same values, regardless of the resolution of the underlyingscreen.
在设备层面,所有你在视图里指定的坐标都必须被转化为像素。然而,在设备坐标空间内映射用户坐标空间的点到像素的工作通常是由系统来完成的。UIKit和Core Graphics都使用一个主要地向量绘图模型,在那里所有的坐标值都是由点指定的。因此,如果你用内核图形绘制一条弧形,你只要给弧形指一个相同值,不用管底层屏幕的分辨率。
When you need to work with images or otherpixel-based technologies such as OpenGL ES, iOS provides help in managing thosepixels. For static image files stored as resources in your application bundle,iOS defines conventions for specifying your images at different pixel densitiesand for loading the image that best matches the current screen resolution.Views also provide information about the current scale factor so that you canadjust any pixel-based drawing code manually to accommodate higher-resolutionscreens. The techniques for dealing with pixel-based content at different screenresolutions is described in“Supporting High-Resolution Screens”inDrawing and Printing Guide for iOS.
当你的工作中需要使用图片或其它基于像素的技术,比如OpenGL ES时,iOS帮助你管理那些像素。对于在应用程序包里作为资源存储的静态图片文件,iOS定义了给图片指定不同像素密度的各种约定,这些约定还包括让图片以最接近当前屏幕分辨率的形式载入。视图还提供了有关当前缩放因子的信息,这样你就能手动调整任何基于像素的绘图来适应高分辨率屏幕。在不同屏幕分辨率下处理基于像素的内容的各种技术在Drawing and Printing Guide for iOS的“Supporting High-Resolution Screens”里有详细描述。