ViewController는 iOS 앱 개발에서 빼놓을 수 없는 요소이다. 구조적으로 어떻게 구성되었는지 알아보고, 어떤 life cycle을 가지는지 이해해보자. 그럼 시작하자.

ViewController

  • View management model

  • 역할

    • view 구성
    • view event 처리
    • data를 view와 연결
  • templates

    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            // VC내부에 property로 있는 view가 화면에 보이기 위해 load 되었을 때 호출됨
            // VC 생성 시점과 view가 보이는 시점은 차이가 있음
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // App이 메모리 부족 경고를 받을 경우 호출됨
        }
    }
    • 메모리 관리는 AppDelegate에서도 가능

초기화

// code
public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)

// storyboard
public init?(coder: NSCoder)
  • parameter

    • nibName: nib 파일명
    • bundle: nib파일이 있는 Bundle(NSBundle) 객체
    • UIViewController.init()인 경우 nil로 넘어옴
  • 활용

    class ViewController: UIViewController {
        override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
            super.init(nibName: nibNameOrnil, bundle: nibBundleOrNil)
    
            // 초기화 코드 작성
            // 해당 시점에는 view가 없음
            // view와 관계없는 object 초기화 용도로 좋음
        }
    }
    
    class ViewController: UIViewController {
        required init?(coder: NSCoder) {
            super.init(coder: coder)
    
            // 상등
        }
    }

Life Cycle

  1. init
  2. loadView
  3. viewDidLoad
  4. viewWillAppear
  5. viewDidAppear
  6. viewWillDisappear
  7. viewDidDisappear
  8. deinit

LoadView

  • view에 대한 customizing 작업
  • 구현하지 않아도 기본적으로 view가 생성되어 load됨
    override func loadView() {
        let view = UIView(frame: UIScreen.main.bounds) // 스크린 크기에 맞춘 view 생성
        view.backgroundColor = UIColor.green
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight] // window의 크기 변경에 맞춰 변하도록 설정
        self.view = view
    }

주의사항

  • init method에서 view에 접근하면 위험함
    • 초기화 작업 중에 viewDidLoad가 호출될 수 있음
    • method 호출 순서가 달라져 버그 발생위험 있음
    • 일반적인 상황
      • viewController가 사용되기 시작할 때 호출됨
    • init method에서 접근
      • view 생성, 초기화 과정에서 호출됨

Container View Controller

  • UIViewController 하위에 ChildViewController를 둘 수 있음
  • 기능에 따라 ViewController를 분리 후, Container ViewController에 모아서 보여줄 수 있음
  • 동일한 생명주기를 가짐

정리

  • UIWindow위에 rootViewController가 올라간다.
  • ViewController에서는 ChildViewController를 가진다.
  • 추가적으로 다른 창을 띄울수도 있고(modal) 이는 presentedViewController로 접근 가능하다.

View

  • 화면을 구성하는데 기본이 되는 class
  • NSObject를 상속한 UIResponder를 상속해서 구성됨
  • CustomView는 UIView를 상속함
  • UIImageView, UILable, UIScrollView...

가능한 것들

  • Drawing
  • Animation
  • Layout
  • subview 관리
  • Event Handling
    • UIResponder 상속하기 때문에, touch와 같은 event에 반응 가능
    • gesture 추가

초기화

  • 형태

    // code
    init(frame:)
    init() // default parameter = CGRect.zero
    
    // storyboard
    init(coder:)
  • templates

    override init(frame: CGRect) {
        super.init(frame: frame)
        // write code
    }
    
    required init?(coder: NScoder) {
        super.init(coder: coder)
        // write code
    }

frame & bounds

  • UIView는 기본적으로 사각형임
  • 이 상태에서 frame, bounds를 통해 크기와 위치 조정
  • CGRect
    • frame, bounds의 자료형
    • x, y, point 및 가로,세로 크기를 가짐
  • point
    • 좌표 체계
    • px * scale임
      • UIScreen.main.scale로 접근 가능
  • frame
    • superview로 부터 상태적인 위치 및 크기
    • 집의 창문이라 생각
  • bounds
    • view의 내부 크기
    • 방의 크기라 생각
    • 창문보다 방이 넓을 수 있고, 창문과 방이 크기가 같을 수 있다.
    • 창문 설치 위치가 고정이라고 했을 때, 방의 위치를 이리거리 움직인다면 방의 내부를 창문으로 볼 수 있을 것이다.
    • 위의 설명 방식으로 동작한다.

Subview 관리

  • 추가
    view.addSubview(subview)
  • 제거
    subview.removeFromSuperView()

LayoutSubviews

  • view 크기 및 bounds들이 변경될 때 호출됨
  • layoutSubviews를 override해서 view의 화면 변화에 따른 subview들의 layout 재조정 가능
  • 보다 깊은 사항은 추가 글을 통해 알아보자

주의 사항

  • view 접근은 반드시 main thread에서 이루어져야 함

Reference

profile
목표와 계획, 그리고 실천의 힘을 믿습니다.

0개의 댓글