7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CGRectを元にカスタマイズCGRectを生成

Posted at

1. 値の再代入禁止について

Objective-Cから関数型のSwiftに変わり、Optional型ではない変数の再代入が禁止されました。
例えばStructで宣言した変数も基本的に再代入は禁止です。(ただし、mutatingメソッド内では可能ですが、ここでは割愛します)

よく使うStruct型の例として、CGRectを見てみましょう

import UIKit

let rectangle = CGRectMake(0, 0, 10, 10) // 10x10の正方形(CGRect)を作成
rectangle.size.width = 20 // 20x10の長方形に長さを変更
// (エラー) --> Cannot assign to the result of this expression

2. 解決策(α)

一度作成したCGRectを変更しようとすると、再代入はダメと怒られてしまいました。
もし値を変更したい場合は、もう一度CGRectMakeしてあげないといけません。

let square = CGRectMake(0, 0, 10, 10)
let rect = CGRectMake(square.origin.x, square.origin.y, 20, square.size.height)

3. 解決策(β)

ただし、CGRectの一部を変更するだけのために、square.originやsquare.sizeを何度も書くのは面倒なので、CGRectMakeの拡張関数を作成してあげます。

// どこを変更するか
enum CGRectChangeAt: Int {
  case X = 0
  case Y, Width, Height
}

/*
** [引数]
** rect: 変更前のCGRect, changeAt: 変更する場所, value: 変更する値
 */
func CGRectMake(rect: CGRect, changeAt: CGRectChangeAt, value: CGFloat) -> CGRect {
  switch changeAt {
  case .X:
    // origin.xを変更
    return CGRectMake(value, rect.origin.y, rect.size.width, rect.size.height)
  case .Y:
    // origin.yを変更
    return CGRectMake(rect.origin.x, value, rect.size.width, rect.size.height)
  case .Width:
    // size.widthを変更
    return CGRectMake(rect.origin.x, rect.origin.y, value, rect.size.height)
  case .Height:
    // size.heightを変更
    return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, value)
  default:
    // 何も変更しない
    return rect
  }
}

拡張版CGRectMakeを利用して、CGRectの値を変更してあげましょう。

let square = CGRectMake(0, 0, 10, 10)
let rect = CGRectMake(square, .Width, 20) // squareを元に、widthを20に設定したCGRectを作成

(追記) おすすめではない方法

mutatingを使えばStruct型の値を変更できますが、関数型言語の方法としては良くないのでオススメできません。

import UIKit

extension CGRect {
  // CGRect内の変数を変更できるようにmutatingメソッドを作成
  mutating func ChangeAt(changeAt: CGRectChangeAt, value: CGFloat) {
    switch changeAt {
    case .X:
      self.origin.x = value
    case .Y:
      self.origin.y = value
    case .Width:
      self.size.width = value
    case .Height:
      self.size.height = value
    case default: break
    }
  }
}

let frame = CGRectMake(0, 0, 10, 10) // CGRectを作成
frame.ChangeAt(.X, value: 10) // x位置を変更

Xcode6ではTop LevelのStructに関してはextensionが無効になるので、このextensionは現在使用できないみたいです。

7
8
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?