안녕하세요. 린다입니다.
예전에 정리했던 뷰의 생명주기에 대해서 더 자세하게 정리해보았어요.
navigationController를 사용해서 완전히 push로 이동하는 경우와
present를 사용하여 모달로 이동하는 경우로 나누어서 정리했습니다.
구현상황) FirstViewController → 버튼 tapped → SecondViewController
+ navigationController를 사용하여 완전히 push로 이동하는 경우
출력 결과
🔥 FirstViewController viewDidLoad
🔥 FirstViewController viewWillAppear
🔥 FirstViewController viewDidAppear
button Tapped!!
🍀 SecondViewController viewDidLoad
🔥 FirstViewController viewWillDisappear
🍀 SecondViewController viewWillAppear
🔥 FirstViewController viewDidDisappear
🍀 SecondViewController viewDidAppear
정리하면 실행 순서는..
ViewDidLoad → willAppear → didAppear → 화면이 처음 뿌려졌을 때 타는 함수
Button Tapped!
ViewDidLoad → 다음 화면의 viewDidLoad
viewWillDisappear → 첫화면이 없어질 예정!!
viewWillAppear → 다음화면 올라오는 중!!
viewdidDisappear →첫화면 없어짐!
viewDidAppear → 다음 화면 다 나타남!
순서이다. 즉,
willDisappear → willAppear → didDisappear → didAppear 순으로
will → did 순으로 실행되면서, disappear → appear 순으로 실행된다.
여기서 다시 Back 버튼을 눌렀을때
🍀 SecondViewController viewWillDisappear
🔥 FirstViewController viewWillAppear
🍀 SecondViewController viewDidDisappear
🔥 FirstViewController viewDidAppear
동일하게 현재 뷰의 will + Disappear부터 실행됨
willDisappear → willAppear → didDisappear → didAppear 순으로
will → did 순으로 실행되면서, disappear → appear 순으로 실행된다.
다시 이동 버튼을 누르면?
button Tapped!!
🍀 SecondViewController viewDidLoad
🔥 FirstViewController viewWillDisappear
🍀 SecondViewController viewWillAppear
🔥 FirstViewController viewDidDisappear
🍀 SecondViewController viewDidAppear
원래 첫화면의 viewDidLoad만 제외하고 모두
현재 뷰의 will + Disappear 순으로 실행되는 것을 확인할 수 있다.
만약에 뒤로가기 제스처로 앞뷰를 슬쩍보기만 하고 가지 않았을 경우는?
상황: SecondViewController 에서 FirstViewController로 제스처 뒤로가기를 했지만, 완전히 이동하지 않고 손을 떼서 SecondViewController에 머무르게 되었을때
🍀 SecondViewController viewWillDisappear
🔥 FirstViewController viewWillAppear
🔥 FirstViewController viewWillDisappear
🔥 FirstViewController viewDidDisappear
🍀 SecondViewController viewWillAppear
🍀 SecondViewController viewDidAppear
"두번째 화면 없어질 예정이에요, 첫번째 화면 뜰예정이에요"가 먼저 실행됨
그치만 여기서 손을 떼서 원상복귀를 하면..
다시 첫번째 화면 사라질예정 → 사라졌어요
두번째 화면 보일예정 → 완료
순서로 실행됨
그렇다면 모달로 이동했을때는?
구현상황) FirstViewController → 모달 버튼 tapped → SecondViewController
🔥 FirstViewController viewDidLoad
🔥 FirstViewController viewWillAppear
🔥 FirstViewController viewDidAppear
modal button Tapped!!
🍀 SecondViewController viewDidLoad
🍀 SecondViewController viewWillAppear
🍀 SecondViewController viewDidAppear
두번째 뷰로 이동을 완료 했을때, Disappear은 실행되지 않음!
그러면 두번째 뷰, 모달을 완전히 내렸을 때는?
🍀 SecondViewController viewWillDisappear
🍀 SecondViewController viewDidDisappear
두번째 뷰의 willDisappear → didDisappear 이 실행됨
(첫번째 뷰는 disappear된 적이 없기 때문에 willappear, didappear이 실행되지 않는것 같음)
뒤로가기 버튼을 만들어서 다시 첫번째로 이동했을때도 동일하게 willDisappear → didDisappear로 실행됨
돌아온 첫 화면에서 다시 모달 이동 버튼을 누르면 ?
modal button Tapped!!
🍀 SecondViewController viewDidLoad
🍀 SecondViewController viewWillAppear
🍀 SecondViewController viewDidAppear
동일하게 viewDidLoad 부터 실행됨
여기서 모달을 밑으로 내리는 제스처를 시작만 해도
(조금만 내려도 == 손을 갖다 대기만 해도)
🍀 SecondViewController viewWillDisappear
// 손을 놓아서 다시 위로 뾰잉하고 올라왔을 때
🍀 SecondViewController viewWillAppear
🍀 SecondViewController viewDidAppear
viewWillDisappear이 실행됨 (did까지 안 감, 완전히 모달 뷰를 제스처로 다 내려야 Diddisappear 실행됨)
그치만 온전히 내려가지 않고 다시 뾰잉!하고 올라온다면
현재뷰의 willAppear → didAppear이 순서로 실행됨
테스트 하면서 사용했던 코드들
FirstViewController
class FirstViewController: UIViewController {
private let text: UILabel = {
let label = UILabel()
label.textColor = .black
label.text = "첫번째 뷰, FirstViewController"
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let button: UIButton = {
let button = UIButton()
button.setTitle("이동", for: .normal)
button.setTitleColor(.black, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
private let modalButton: UIButton = {
let button = UIButton()
button.setTitle("모달", for: .normal)
button.setTitleColor(.black, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
makeUI()
setupButton()
print("🔥 FirstViewController viewDidLoad")
}
}
extension FirstViewController {
func makeUI() {
view.backgroundColor = .white
view.addSubview(text)
view.addSubview(button)
view.addSubview(modalButton)
NSLayoutConstraint.activate([
text.centerXAnchor.constraint(equalTo: view.centerXAnchor),
text.centerYAnchor.constraint(equalTo: view.centerYAnchor),
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.topAnchor.constraint(equalTo: text.bottomAnchor, constant: 20),
modalButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
modalButton.topAnchor.constraint(equalTo: button.bottomAnchor, constant: 20)
])
}
func setupButton() {
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
modalButton.addTarget(self, action: #selector(modalButtonTapped), for: .touchUpInside)
}
@objc func buttonTapped() {
print("button Tapped!!")
let naviVC = SecondViewController()
self.navigationController?.pushViewController(naviVC, animated: true)
}
@objc func modalButtonTapped() {
print("modal button Tapped!!")
let naviVC = SecondViewController()
present(naviVC, animated: true)
}
}
extension FirstViewController {
override func viewWillAppear(_ animated: Bool) {
print("🔥 FirstViewController viewWillAppear")
}
override func viewWillDisappear(_ animated: Bool) {
print("🔥 FirstViewController viewWillDisappear")
}
override func viewDidAppear(_ animated: Bool) {
print("🔥 FirstViewController viewDidAppear")
}
override func viewDidDisappear(_ animated: Bool) {
print("🔥 FirstViewController viewDidDisappear")
}
}
SecondViewController
class SecondViewController: UIViewController {
private let text: UILabel = {
let label = UILabel()
label.textColor = .black
label.text = "두번째 뷰, SecondViewController"
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let modalBackButton: UIButton = {
let button = UIButton()
button.setTitle("뒤로가기", for: .normal)
button.setTitleColor(.black, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
print("🍀 SecondViewController viewDidLoad")
makeUI()
setupButton()
}
}
extension SecondViewController {
func makeUI() {
view.backgroundColor = .white
view.addSubview(text)
view.addSubview(modalBackButton)
NSLayoutConstraint.activate([
modalBackButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
modalBackButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20),
text.centerXAnchor.constraint(equalTo: view.centerXAnchor),
text.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
}
extension SecondViewController {
func setupButton() {
modalBackButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
}
@objc func backButtonTapped() {
dismiss(animated: true)
print("modal back Button tapped!")
}
override func viewWillAppear(_ animated: Bool) {
print("🍀 SecondViewController viewWillAppear")
}
override func viewWillDisappear(_ animated: Bool) {
print("🍀 SecondViewController viewWillDisappear")
}
override func viewDidAppear(_ animated: Bool) {
print("🍀 SecondViewController viewDidAppear")
}
override func viewDidDisappear(_ animated: Bool) {
print("🍀 SecondViewController viewDidDisappear")
}
}
면접때 탈탈 털리고.. 다시 유킷으로 돌아왔습니다.
유킷을 오랜만에 보니 어질어질 하네요 ^^… 스유도 곧 이렇게 정리해서 올려볼게요.
이상하거나 추가하면 좋은 부분이 있다면 댓글주세욥!
'Swift > UIKit' 카테고리의 다른 글
[UIKit] Firebase로 이메일,비밀번호 로그인 / 구글로그인 구현하기 (1) | 2023.08.27 |
---|---|
[UIKit] UIKit, Firebase 연결하기 (0) | 2023.08.26 |