Objective-Cの時から、UIViewの位置を決める時のframe操作がまどろっこしくてしかたなかった人は多かったんじゃないかと思います。

SwiftのCGRectはそれなりに便利関数が追加されたとは言え、やっぱりまだまだめんどいです。Autolayoutを使ったほうがいい場合もありますが、あれはあれでめんどくさいのでちょちょっとframeで動かしたいこともよくあります。でも、UIView内のframeって中途半端に中身の上書き禁止になっててめんどくさい。

例えばあるUIViewを、別のUIViewの右端に揃えたい時。

someView.right = otherView.right

って書きたいやん。

大きさの違う円を、真ん中合わせて二重丸っぽくしたい時は、

someCircle.center = otherCircle.center

って書きたいやん。

あるUIViewを、10ポイントだけ空けて別のUIViewの隣に置きたい時は、

someView.left = otherView.right + 10

って書きたいやん。

という願いを叶えるためのextensionを作ったので置いておきます。めんどくさいからまだsubmoduleにはしてません。気が向いたら。

SPONSERD LINK
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// UIView+extension.swift

extension UIView {
  var x: CGFloat {
    get {
      return frame.minX
    }
    set {
      frame = CGRect(newValue, frame.minY, frame.width, frame.height)
    }
  }
  
  var y: CGFloat {
    get {
      return frame.minY
    }
    set {
      frame = CGRect(frame.minX, newValue, frame.width, frame.height)
    }
  }
  
  var width: CGFloat {
    get {
      return frame.width
    }
    set {
      frame = CGRect(frame.minX, frame.width, newValue, frame.height)
    }
  }
  
  var height: CGFloat {
    get {
      return frame.height
    }
    set {
      frame = CGRect(frame.minX, frame.minY, frame.width, newValue)
    }
  }
  
  var top: CGFloat {
    get {
      return y
    }
    set {
      y = newValue
    }
  }
  
  var bottom: CGFloat {
    get {
      return frame.maxY
    }
    set {
      frame = CGRect(x, newValue - height, width, height)
    }
  }
  
  var left: CGFloat {
    get {
      return x
    }
    set {
      x = newValue
    }
  }
  
  var right: CGFloat {
    get {
      return frame.maxX
    }
    set {
      frame = CGRect(newValue - width, y, width, height)
    }
  }
  
  var midX: CGFloat {
    get {
      return frame.midX
    }
    set {
      frame = CGRect(newValue - width / 2, y, width, height)
    }
  }
  
  var midY: CGFloat {
    get {
      return frame.midY
    }
    set {
      frame = CGRect(x, newValue - height / 2, width, height)
    }
  }
  
  var center: CGPoint {
    get {
      return CGPoint(frame.midX, frame.midY)
    }
    set {
      frame = CGRect(newValue.x - width / 2, newValue.y - height / 2, width, height)
    }
  }
}

このままやとコンパイルエラーになるので、下記のミニextensionも一緒にどうぞ。こちらは、いちいちx: とかwidth: とかのキーワードを入れなくてもよくするinitializer達です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// CoreGraphics+extension.swift

extension CGPoint {
  init(_ x: CGFloat, _ y: CGFloat) {
    self.x = x
    self.y = y
  }
}

extension CGSize {
  init(_ width: CGFloat, _ height: CGFloat) {
    self.width = width
    self.height = height
  }
}

extension CGRect {
  init(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) {
    self.origin = CGPoint(x, y)
    self.size = CGSize(width, height)
  }
}