swift之CGRect、CGSize和CGPoint

不要再这样写了

let rect = CGRectMake(0, 0, 100, 100)
let point = CGPointMake(0, 0)
let size = CGSizeMake(100, 100)

要这样写

let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
let size = CGSize(width: 100, height: 100)
let point = CGPoint(x: 0, y: 0)

带来的好处是,可读性强,并且不再仅支持float类型啦~
看一下系统的定义

extension CGRect {
    public init(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat)
    public init(x: Double, y: Double, width: Double, height: Double)
    public init(x: Int, y: Int, width: Int, height: Int)
}

public func CGRectMake(x: CGFloat, 
                     _ y: CGFloat, 
                 _ width: CGFloat, 
                _ height: CGFloat) -> CGRect

不要再这样写了~

let rect = CGRectZero
let size = CGSizeZero
let point = CGPointZero

改成这样吧

let rect = CGRect.zero
let size = CGSize.zero
let point = CGPoint.zero

获取值

如果你曾经或任然是一名优秀的OC开发者,你应该写过这样的代码来获取结构体中的值:

CGRect frame = CGRectMake(0, 0, 100, 100)
CGFloat width = CGRectGetWidth(frame)
CGFloat height = CGRectGetHeight(frame)

不过不妨先思考一下,为什么不能直接获取值呢?比如这样:

CGFloat width = frame.size.width
CGFloat height = frame.size.height
For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics.— Apple, CGGeometry Reference Documentation

(译者注:)考虑两个CGRect,第一个origin是[0,0],size是[10, 10]。第二个的origin是[10,10],size是[-10, -10]。两者其实是等价的,无论是OC还是Swift都支持这两种写法。问题在于,在OC中,获取结构体的属性就直接获取到它的真实值了,这个值有可能为负。所以OC建议我们调用系统API而不是直接获取值,而在Swift中,width、height等被设计为计算属性,自然就不存在这样的问题了。

由于系统提供了完备的API,很多人觉得不直接获取值也不是什么问题。不过Swift提供了简单的点语法表达式,将我们从这种不美观的API中解放出来:

let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
let width = frame.width
let height = frame.height
let maxX = frame.maxX
let maxY = frame.maxY
可变性

let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
let view = UIView(frame: frame)
view.frame.origin.x += 10
现在,你不仅可以直接修改结构体中的某个值,还可以直接替换整个子结构体:

let view = UIView(frame: .zero)
view.frame.size = CGSize(width: 10, height: 10)
view.frame.origin = CGPoint(x: 10, y: 10)
单单这个特性就足够我们放弃OC,投入Swift的怀抱了。我们不必非得重新创建一个结构体实例再修改了,不到两年前,我们OC开发者还被迫写下这样的代码:

CGRect frame = CGRectMake(0, 0, 100, 100);
UIView *view = [[UIView alloc] initWithFrame: frame];
CGRect newFrame = view.frame;
newFrame.size.width = view.frame.origin.x + 10;
view.frame = newFrame;

我不知道你怎么想,但是写出这样的代码快要把我逼疯了。根据view的frame重新创建结构体,修改它,然后再把view的frame改成这个结构体,再见了,再也不见!

最后说一句,以上这些改变还适用于UIKit中的其他结构体:

// UIEdgeInsets
var edgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
edgeInsets.top += 10

// UIOffset
var offset = UIOffset(horizontal: 10, vertical: 10)
offset.vertical += 10

参考文章:http://www.cocoachina.com/ios/20160224/15359.html

你可能感兴趣的:(swift之CGRect、CGSize和CGPoint)