[swift] BASIC_05. ViewController Life Cycle (뷰 컨트롤러 생명주기)


ViewController Life Cycle

생명주기

  • Appearing: View가 화면에 나타나는 중
  • Appeard: View가 화면에 나타나는게 완료된 상태
  • Disappearing: View가 화면에서 사라지는 중
  • Disappeared: View가 화면에서 사라진 상태



viewDidLoad()

  • viewController의 모든 View들이 메모리에 로드됐을 때 호출
  • 메모리에 처음 로드될 때 한 번만 호출
  • 보통 딱 한 번 호출될 행위들을 이 메소드 안에 정의 함
  • View와 관련된 추가적인 초기화 작업, 네트워크 호출



viewWillAppear()

  • View가 뷰 계층에 추가되고, 화면에 보이기 직전에 매 번 호출
  • 다른 View로 이동했다가 돌아오면 재호출
  • View와 관련된 추가적인 초기화 작업



viewDidAppear()

  • ViewController의 View가 뷰 계층에 추가된 후 호출
  • View를 나타낼 때 필요한 추가 작업
  • 애니메이션을 시작하는 작업



viewWillDisappear()

  • ViewController의 View가 뷰 계층에서 사라지기 전 호출
  • View가 생성된 후 작업한 내용을 되돌리는 작업
  • 최종적으로 데이터를 저장하는 작업



viewDidDisappear()

  • ViewController의 View가 뷰 계층에서 사라진 뒤 호출
  • View가 사라지는 것과 관련된 추가 작업

[swift] BASIC_04. ScreenTransition (화면 전환)


화면 전환

화면 전환 방법

소스코드를 통해 전환하는 방식과, Storyboard를 통해 전환하는 방식이 있다.

  • View Controller의 View 위에 다른 View를 가져와 전환하기
  • View Controller에서 다른 View Controller를 호출하여 전환하기
  • Navigation Controller를 사용하여 화면 전환하기
  • 화면 전환용 객체 Segueway(세그웨이)를 사용하여 화면 전환하기




View Contorller에서 다른 View Controller를 호출하여 전환하기

Declaration 1

func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil)

Parameters 1

viewControllerToPresent
 - The view controller to display over the current view controller's content.

flag
 - Pass true to animated the presentation; otherwise, pass false

completion
 - The block to execute after the presentation finishes. This block has no return value and takes no parameters. You may specify nil for this parameter.



Declaration 2

func dismiss(animated flag: Bool, completion: (() -> Void)? = nil)

Parameters 2

flag
 - Pass true to animate the transition.

completion
 - The block to execute after the view controller is dismissed. This block has no return value and takes no parameters. You may specify nil for this parameter.




Navigation Controller를 사용하여 화면 전환하기

Declaration 1

func pushViewController(_ viewController: UIViewController, animated: Bool)

Parameters 1

viewController
 - The view controller to push onto the stack. This object cannot be a tab bar controller. If the view controller is already on the navigation stack, this method throws an exception.

 animated
  - Specify true to animate the transition or false if you do not want the transition to be animated. You might specify false if you are setting up the navigation controller at launch time.



Declaration 2

func popViewController(animated: Bool) -> UIViewController?

Parameters 2

animated
 - Set this value to true to animate the transition. Pass false if you are setting up a navigation controller before its view is displayed.

Return Value

The view controller that was popped from the stack.




화면 전환용 객체 Segueway(세그웨이)를 사용하여 화면 전환하기

Segueway

  • 세그웨이에는 두 개의 ViewController 사이에 연결된 화면 전환 객체를 의미한다.
  • 스토리보드를 통해 출발지와 목적지를 직접 지정하는 방식을 말한다.
  • Segueway를 사용하면 따로 코드를 사용하지 않고 화면을 전환할 수 있다.



Action Segueway

  • 출잘점이 ViewController 자체인 경우



Manual Segueway

  • 출발점이 Button 등 ViewController가 아닌 경우를 말한다.
  • Action Segueway, Trigger Segueway라고도 한다.



Action Segueway 종류

  • Show: 가장 일반적인 Segueway로 Navigation Controller를 사용하면 화면 전환 시 ViewController가 ViewStack에 쌓이게 된다.
  • Show Detail: 스플릿 뷰에서 주로 사용한다. 아이폰에서 사용하게 되면 Show Segueway Action과 똑같이 동작하지만, 아이패드에서 사용하게 되면 스플릿 뷰에 Master&Slave 구조로 작동한다.
  • Present Modally: 이전 ViewController를 덮으면서 새로운 화면이 나타나게 된다.
  • Present As Popover: 아이패드에서 사용되는 것으로, 팝업 창을 띄울 때 사용한다. (아이폰에서는 사용하지 않는다.)
  • Custom: 사용자가 원하는 방식으로 커스텀하여 사용한다.

[swift] BASIC_04-01. ScreenTransition Code (화면 전환 코드)


화면 전환

화면 전환 방법

소스코드를 통해 전환하는 방식과, Storyboard를 통해 전환하는 방식이 있다.

  • View Controller의 View 위에 다른 View를 가져와 전환하기
  • View Controller에서 다른 View Controller를 호출하여 전환하기
  • Navigation Controller를 사용하여 화면 전환하기
  • 화면 전환용 객체 Segueway(세그웨이)를 사용하여 화면 전환하기




Code Push

ViewController.swift

import UIKit

class ViewController: UIViewController, SendDataDelegate {

    @IBOutlet weak var lblName: UILabel!
    var name: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        print("ViewController is loaded")
    }

    @IBAction func btnCodePush(_ sender: UIButton) {
        guard let viewController = self.storyboard?.instantiateViewController(withIdentifier: "CodePushViewController") as? CodePushViewController else { return }
        
        viewController.name = "JunHyeok"
        
        self.navigationController?.pushViewController(viewController, animated: true)
    }

}



CodePushViewController.swift


import UIKit

class CodePushViewController: UIViewController {

    @IBOutlet weak var lblName: UILabel!
    var name: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if let name = name {
            self.lblName.text = name
            self.lblName.sizeToFit()
        }
    }
    
    @IBAction func btnBack(_ sender: UIButton) {
        self.navigationController?.popViewController(animated: true)
    }
    
}




Code Present

ViewController.swift

import UIKit

class ViewController: UIViewController, SendDataDelegate {

    @IBOutlet weak var lblName: UILabel!
    var name: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("ViewController is loaded")
    }
    
    @IBAction func btnCodePresent(_ sender: UIButton) {
        guard let viewController = self.storyboard?.instantiateViewController(withIdentifier: "CodePresentViewController") as? CodePresentViewController else { return }
        
        viewController.modalPresentationStyle = .fullScreen
        viewController.name = "JunHyeok"
        viewController.delegate = self
        self.present(viewController, animated: true, completion: nil)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let viewController = segue.destination as? SuguePushViewController {
            viewController.name = "JunHyeok"
        } else if let viewController = segue.destination as? SuguePresentViewController {
            viewController.name = "JunHyeok1"
        }
    }
    
    func sendData(name: String) {
        self.lblName.text = name
        self.lblName.sizeToFit()
    }

}



CodePresentViewController.swift

import UIKit

protocol SendDataDelegate: AnyObject {
    func sendData(name: String)
}

class CodePresentViewController: UIViewController {

    @IBOutlet weak var lblName: UILabel!
    var name: String?
    weak var delegate: SendDataDelegate? // delegate 변수 앞에는 weak를 붙인다.(안붙이면 메모리 누수가 발생)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if let name = name {
            self.lblName.text = name
            self.lblName.sizeToFit()
        }
    }
    
    @IBAction func btnBack(_ sender: UIButton) {
        self.delegate?.sendData(name: "JunHyeok")
        self.presentingViewController?.dismiss(animated: true, completion: nil)
    }
    
}




Seguement

Main.storyboard

storyboard



SeguePushViewController.swift

import UIKit

class SuguePushViewController: UIViewController {
    
    @IBOutlet weak var lblName: UILabel!
    var name: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("SegueViewController is loaded")
        if let name = name {
            self.lblName.text = name
            self.lblName.sizeToFit()
        }
    }
    
    @IBAction func btnBackbutton(_ sender: UIButton) {
        self.navigationController?.popViewController(animated: true)
        self.navigationController?.popToRootViewController(animated: true)
    }
    
}



SeguePresentController.swift

import UIKit

class SuguePresentViewController: UIViewController {
    
    @IBOutlet weak var lblName: UILabel!
    var name: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        if let name = name {
            self.lblName.text = name
            self.lblName.sizeToFit()
        }
    }
    
    @IBAction func btnBackButton(_ sender: UIButton) {
        self.presentingViewController?.dismiss(animated: true, completion: nil)
    }

}

[swift] BASIC_03. UINavigationController


View Controller

Content View Controller

  • 화면을 구성하는 뷰를 직접 구현하고 관련된 이벤트를 처리하는 뷰 컨트롤러



Container View Conroller

  • 하나 이상의 Child View Controller를 가지고 있다.
  • 하나 이상의 Child View Controller를 관리하고 레이아웃과 화면 전환을 담당한다.
  • 화면 구성과 이벤트 관리는 Child View Controller에서 한다.
  • Container View Controller는 대표적으로 Navigation Controller와 TabBar Controller가 있다.




UINavigationController

UINavigationController

  • 계층 구조로 구성된 content를 순차적으로 보여주는 container view controller이다.



  • Navigation은 Stack 구조이다. stack



navigationBar

[swift] BASIC_02. UIViewController, AutoLayout


ViewController

UIView

  • 화면의 직사각형 영역에 대한 내용을 관리하는 개체



ViewController

  • 앱의 근간을 이루는 객체
  • 모든 앱은 최소한 하나 이상의 뷰 컨트롤러를 가지고 있다.



ViewController의 주요 역할

  • 데이터 변화에 따라서 view 컨텐츠를 업데이트
  • view들과 함께 사용자 상호작용에 응답
  • view를 리사이징하고 전체적인 인터페이스의 레이아웃 관리
  • 다른 viewController들과 함께 앱을 구성




AutoLayout

AutoLayout

  • 제약 조건(Constraints)를 이용하여 뷰의 위치를 지정하는 것
  • 아이폰의 다양한 해상도 비율에 대응하기 위해 나온 것
  • 다른 해상도에서도 화면을 똑같이 보여주기 위해 사용



StoryBoard

  • IOS앱에 사용자 인터페이스를 시각적으로 표현하여
  • 컨텐츠 화면과 화면간의 연결을 보여주는 도구



Constraint

constraint



align

정렬 제약 조건
align



Resolve Auto Layout Issues

AutoLayout 관련 Issues들을 해결하는 것이다.
업데이트, 누락된 제약을 추가, 삭제, 사용할 수 있다.
resolveAutoLayoutIssues