Edited at

CGRectのSwiftっぽい扱い方

More than 3 years have passed since last update.


Objective-C時代のCGRectまわり :confused:

こんなときよくあると思います。


  • CGRectからwidthだけとりたい

  • 最大のYの位置をとりたい

  • あるCGRectにCGPointが含まれてるとかを判定したい

Objective-CのときはGlobalな関数の形で用意されていました。名前も長いので構造体の値を辿るのとそんなにコード量は変わらないのが残念でしたが、便利なのでよく使っていました。

追記: 構造体でアクセスした場合と関数で取得した場合に値が異なることがあるので注意してください。詳しくはコメント欄に書いてあります。


// 例1: 最小のx
CGFloat minX = CGRectGetMinX(self.view.frame); // 関数
CGFloat minX = self.view.frame.origin.x; // 構造体アクセス

// 例2: 幅
CGFloat width = CGRectGetWidth(self.view.frame); // 関数
CGFloat width = self.view.frame.size.width; // 構造体アクセス

// 例3: ゼロで初期化したCGRect
CGRect zeroRect = CGRectZero; // 定数
CGRect zeroRect = CGRectMake(0, 0, 0, 0); // zeroで初期化

// 例4: RectにPointが含まれているかどうか
CGRect rect = CGRectMake(0, 0, 100, 100);
CGPoint point = CGPointMake(50, 50);
BOOL isContainsPoint = CGRectContainsPoint(rect, point); // => YES


Swift時代 :100:

Swiftになってこんなに直感的に書けるようになりました。CGRectに対してそのままメソッド呼び出しやプロパティアクセスできるようになります:tada:

// 例1: 最小のx

let minX = self.view.frame.minX

// 例2: 幅 (今まではframe.size.widthってやる必要があった)
let width = self.view.frame.width

// 例3: ゼロで初期化したCGRect
let zeroRect = CGRect.zeroRect

// 例4: RectにPointが含まれているかどうか
let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
let point = CGPoint(x: 50, y: 50)
let isContainsPoint = rect.contains(point) // => true


Swiftの便利CGRect操作一覧 :dancer:

CGRectMakeやCGRectZero、CGRectGetWidthとかも使うことができちゃうのでこんなに便利なやつが生えてたの知らない人もいるんじゃないんでしょうか。なので、Swiftからはこっちを使いましょう!


extension CGRect {
static var zeroRect: CGRect { get }
static var nullRect: CGRect { get }
static var infiniteRect: CGRect { get }
init(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat)
init(x: Double, y: Double, width: Double, height: Double)
init(x: Int, y: Int, width: Int, height: Int)
var width: CGFloat { get }
var height: CGFloat { get }
var minX: CGFloat { get }
var midX: CGFloat { get }
var maxX: CGFloat { get }
var minY: CGFloat { get }
var midY: CGFloat { get }
var maxY: CGFloat { get }
var isNull: Bool { get }
var isEmpty: Bool { get }
var isInfinite: Bool { get }
var standardizedRect: CGRect { get }
mutating func standardize()
var integerRect: CGRect { get }
mutating func integerize()
func rectByInsetting(#dx: CGFloat, dy: CGFloat) -> CGRect
mutating func inset(#dx: CGFloat, dy: CGFloat)
func rectByOffsetting(#dx: CGFloat, dy: CGFloat) -> CGRect
mutating func offset(#dx: CGFloat, dy: CGFloat)
func rectByUnion(withRect: CGRect) -> CGRect
mutating func union(withRect: CGRect)
func rectByIntersecting(withRect: CGRect) -> CGRect
mutating func intersect(withRect: CGRect)
func rectsByDividing(atDistance: CGFloat, fromEdge: CGRectEdge) -> (slice: CGRect, remainder: CGRect)
func contains(rect: CGRect) -> Bool
func contains(point: CGPoint) -> Bool
func intersects(rect: CGRect) -> Bool
}