UIKit에 정의된 UIView 살펴보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@available(iOS 2.0, *)
@MainActor open class UIView : UIResponder, NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusItem, UIFocusItemContainer, CALayerDelegate {
public init(frame: CGRect)
public init?(coder: NSCoder)
open func willMove(toSuperview newSuperview: UIView?)
open func didMoveToSuperview()
open func willMove(toWindow newWindow: UIWindow?)
open func didMoveToWindow()
open func layoutSubviews()
open func draw(_ rect: CGRect)
이전 UIViewController 라이프사이클에서도 봤었던 @MainActor
는 Swift 5.5에서 나온 개념으로 메인 쓰레드에서 실행되도록 보장하는 역할 이라고 보시면 됩니다.
이제 하나씩 자세히 살펴 보겠습니다.
init
1
2
3
public init(frame: CGRect)
public init?(coder: NSCoder)
init?(coder: NSCoder)
는 스토리보드를 통해 생성할 때 호출됩니다.
init(frame: CGRect)
는 코드 베이스로 생성할 때 호출됩니다.
willMove(toSuperview:)
1
open func willMove(toSuperview newSuperview: UIView?)
뷰가 뷰 계층에 추가되기 전에 호출됩니다.
만약 newSuperview
가 nil
이라면, 뷰가 뷰 계층에서 제거되는 것을 의미한다고 보시면 됩니다.
didMoveToSuperview()
1
open func didMoveToSuperview()
뷰가 뷰 계층에 추가된 후에 호출됩니다.
willMove(toWindow:)
1
open func willMove(toWindow newWindow: UIWindow?)
뷰가 윈도우에 추가되기 전에 호출됩니다. willMove(toSuperview:)와 마찬가지로 newWindow
가 nil
이라면, 뷰가 윈도우에서 제거되는 것을 의미한다고 보시면 됩니다.
didMoveToWindow()
1
open func willMove(toWindow newWindow: UIWindow?)
뷰가 윈도우에 추가된 후 호출됩니다.
layoutSubviews()
1
open func layoutSubviews()
뷰의 서브뷰들의 레이아웃에 대한 처리가 완료 되었을 때 호출됩니다.
그리고 1번만 호출하는게 아니라 뷰의 크기가 변경될 때마다 호출됩니다.
draw(_:)
1
open func draw(_ rect: CGRect)
뷰가 추가되어 화면에 추가되어 좌표 설정이 되면 호출됩니다.
추가적으로, setNeedsDisplay()
메서드가 호출될 때 자동으로 draw 메서드가 호출됩니다.
CGRect가 .zero라면 호출되지 않습니다.
Test 코드 예시
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
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let view = CustomView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
self.view.addSubview(view)
}
}
class CustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
print("init(frame: CGRect)")
}
override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
print("willMove(toSuperview newSuperview: UIView?)")
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
print("didMoveToSuperview()")
}
override func willMove(toWindow newWindow: UIWindow?) {
super.willMove(toWindow: newWindow)
print("willMove(toWindow newWindow: UIWindow?)")
}
override func didMoveToWindow() {
super.didMoveToWindow()
print("didMoveToWindow()")
}
override func layoutSubviews() {
super.layoutSubviews()
print("layoutSubviews()")
}
override func draw(_ rect: CGRect) {
super.draw(rect)
print("draw(_ rect: CGRect)")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Test 결과 콘솔
1
2
3
4
5
6
7
8
init(frame: CGRect)
willMove(toSuperview newSuperview: UIView?)
didMoveToSuperview()
willMove(toWindow newWindow: UIWindow?)
didMoveToWindow()
layoutSubviews()
layoutSubviews()
draw(_ rect: CGRect)