개발하는 뚝딱이

[iOS] view's layout behavior 본문

iOS

[iOS] view's layout behavior

개발자뚝딱이 2021. 3. 17. 23:28

뷰 컨트롤러에 서브뷰를 추가했을 때 종종 레이아웃에 관련하여 문제가 발생하곤 합니다.

viewDidLoad()에서 서브뷰의 프레임이 변경되거나, 레이어를 추가해줄 때, 코드로 뷰를 추가하는 등의 행동이 의도대로 실행되지 않을 때가 종종 있습니다.

뷰 컨트롤러의 viewDidLoad()가 실행되는 시점은, 뷰가 생성되어 메모리에 할당되었을 뿐 뷰 계층구조에 뷰가 추가되지 않았기 때문입니다. 이참에 뷰의 레이아웃에 관련된 메서드를 모두 정리해보았습니다.

 

뷰 컨트롤러에 대해 알아보기 ⏩ ttuk-ttak.tistory.com/73?category=917081

 


 

UIViewController의 생명주기

 

viewDidLoad(_:) 뷰가 메모리에 할당되었을 때

viewWillAppear(_:) 뷰가 계층구조에 추가되기 직전에

viewDidAppear(_:) 뷰가 계층구조에 추가된 후

viewWillDisappear(_:) 뷰가 계층구조에서 삭제되기 직전에

viewDidDisappear(_:) 뷰가 계층구조에 삭제된 후

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("[1] View Did Load")
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("[1] View Will Appear")
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("[1] View Did Appear")
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        print("[1] View Will Disappear")
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        print("[1] View Did Disappear")
    }
    
    @IBAction func showNextViewController(_ sender: UIButton) {
        guard let nextVC = storyboard?.instantiateViewController(identifier: SecondViewController.identifier) else { return }
        self.present(nextVC, animated: true, completion: nil)
    }
}

class SecondViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("[2] View Did Load")
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("[2] View Will Appear")
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("[2] View Did Appear")
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        print("[2] View Will Disappear")
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        print("[2] View Did Disappear")
    }
    
    
    @IBAction func close(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }

}

 

 

앱을 실행시켰을 때, ViewController가 실행됩니다.

아래와 같이 결과가 콘솔창에 출력됩니다.

[1] View Did Load
[1] View Will Appear
[1] View Did Appear

 

 

 

 

첫번째 뷰에서 버튼을 눌러, SecondViewController가 호출됩니다.

[1] View Did Load
[1] View Will Appear
[1] View Did Appear

// 새로 찍힌 로그들
[2] View Did Load
[2] View Will Appear
[2] View Did Appear

 

 

 

SecondViewController의 버튼을 눌러 뷰 컨트롤러를 닫아주었습니다.

[1] View Did Load
[1] View Will Appear
[1] View Did Appear
[2] View Did Load
[2] View Will Appear
[2] View Did Appear

// 새로 찍힌 로그들
[2] View Will Disappear
[2] View Did Disappear