参考文章:CGGeometry
GRect 用于表示屏幕上绘制的所有视图的 frame,一个程序员操作矩形几何体的能力决定着他在图形编程上的成功。
变换
- 几何变换,这些函数返回在传入的矩形中做某些特定操作后的 CGRect
CGRectOffset
CGRectOffset: 返回一个原点在源矩形基础上进行了偏移的矩形
CGRect CGRectOffset(
CGRect rect,
CGFloat dx,
CGFloat dy
)
注意,用这个你只改变了矩形的原点。它不仅能让你在同时改变水平和垂直位置的时候减少一行代码,更重要的是,它所表示的平移比直接分开操作原点的值更具有几何意义。
CGRectInset
CGRectInset: 返回一个与源矩形共中心点的,或大些或小些的新矩形。
CGRect CGRectInset(
CGRect rect,
CGFloat dx,
CGFloat dy
)
想一个视图中的视图更好看吗?用CGRectInset给它设置一个 10pt 的边距吧。需要记住的是,矩形将围绕它的中心点进行缩放,左右分别增减dx(总共2 x dx),上下分别增减 dy(总共 2 x dy)。
如果你用 CGRectInset 作为缩放矩形的快捷方法,一般通用的做法是嵌套调用CGRectOffset,把CGRectInset的返回值作为CGRectOffset的参数。
CGRectIntegral
CGRectIntegral: 返回包围源矩形的最小整数矩形。
CGRect CGRectIntegral (
CGRect rect
)
将CGRect 取整到最近的完整点是非常重要的。小数值会让边框画在像素边界处。因为像素已经是最小单元(不能再细分),小数值会使绘制时取周围几个像素的平均值,这样看起来就模糊了。
CGRectIntegral 将表示原点的值向下取整,表示大小的值向上取整,这样就保证了你的绘制代码平整地对齐到像素边界。
作为一个经验性的原则,如果你在执行任何一个可能产生小数值的操作(例如除法,CGGetMid[X|Y],或是 CGRectDivide),在把一矩形作为视图的边框之前应该用CGRectIntegral正则化它。
从技术上讲,坐标系讲的是点,而视网膜屏一个点中有四个像素,所以它在奇数像素± 0.5f处绘制也不会产生模糊。
取值辅助函数
CGRectGet[Min|Mid|Max][X|Y]
- CGRectGetMinX
- CGRectGetMinY
- CGRectGetMidX
- CGRectGetMidY
- CGRectGetMaxX
- CGRectGetMaxY
这六个函数返回矩形x或y的最小、中间或最大值,原型如下:
CGFloat CGRectGet[Min|Mid|Max][X|Y] (
CGRect rect
)
用这些函数代替诸如frame.origin.x + frame.size.width之类的代码将更加清晰、语义上更为生动的(特别是用取中间和取最大函数)。
CGRectGet[Width|Height]
CGRectGetHeight: 返回矩形的高度。
CGFloat CGRectGetHeight (
CGRect rect
)
CGRectGetWidth: 返回矩形的宽度。
CGFloat CGRectGetWidth (
CGRect rect
)
跟之前的函数一样,用CGRectGetWidth 和 CGRectGetHeight返回CGRect的size成员更可取。这绝不只是节省了几个字符,语义上的清晰胜过简洁。
常量
这里列出了三个我们必须了解的特殊矩形值,它们都有一些独一无二的属性:
CGRectZero, CGRectNull,和 CGRectInfinite
-
const CGRect CGRectZero: 一个原点在(0, 0),且长宽均为 0 的常数矩形。这个零矩形与 CGRectMake(0.0f, 0.0f, 0.0f, 0.0f) 是等价的。
-
const CGRect CGRectNull: 空矩形。这个会在,比如说,求两个不相交的矩形的相交部分时返回。注意,空矩形不是零矩形。
-
const CGRect CGRectInfinite: 无穷大矩形。
CGRectZero 可能是所有这些特殊矩形中最有用的了。当初始化一个视图时,它们的边框通常设置为CGRectZero,把布局放到 -layoutSubviews中。
CGRectNull 跟 CGRectZero 是两回事,尽管它隐隐约约让你感觉到NULL == 0。这个值在概念上与NSNotFound相近,所以它表示预期值的缺失。请注意函数可能返回 CGRectNull,同时也应让它能正确处理传入的CGRectIsNull。
CGRectInfinite 是以上所有当中最有异国风情的,并且有一些最有趣的属性。它与所有的点或矩形相交,包含所有矩形,且它与任何矩形的并集等于它自身。用 CGRectIsInfinite 来检查一矩形是否为无限大。
最复杂、最容易误解、也最有用的CGGeometry 函数:CGRectDivide。
CGRectDivide
CGRectDivide: 将源矩形分为两个子矩形。
void CGRectDivide(
CGRect rect,
CGRect *slice,
CGRect *remainder,
CGFloat amount,
CGRectEdge edge
)
CGRectDivide 用以下方式将矩形分割为两部分:
- 传入一个矩形并选择一条edge(上,下,左,右);
- 平行那个边在矩形里量出amount的长度;
- 从edge 到量出的amount区域都保存到slice 参数中;
- 剩余的部分保存到remainder 参数中。
其中 edge 参数是一个CGRectEdge 枚举类型:
enum CGRectEdge {
CGRectMinXEdge,
CGRectMinYEdge,
CGRectMaxXEdge,
CGRectMaxYEdge
}
CGRectDivide 用于在几个视图之间分割可用空间真是太完美了(把它在随后的remainder容纳多于两个的视图)。下次当你需要手机布局一个UITableViewCell时试试吧。CGRectDivide is perfect for dividing up available space among several views (call it on subsequent remainder amounts to accommodate more than two views). Give it a try next time you're manually laying-out a UITableViewCell.
综上所述,如果你不重视 Geometry 类的话将会怎样...
网友评论