main story board 안쓰기

Groot·2022년 6월 27일
0

TIL

목록 보기
26/153
post-thumbnail

TIL

🌱 난 오늘 무엇을 공부했을까?

📌 View(Navigation controller)를 코드로 구현하면서 View 설정에 사용한 코드 추적해보기

📍 Scene Delegate

  • iOS 13부터 View Life Cycle은 Scene Delegate에서 처리한다.
  • View를 구성하는 화면도 Scene Delegate에 처리해야 하지 않을까?

🔗 SceneDelegate.swift 초기 화면

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // 이 메서드를 사용하여 UIWindow 'window'을 선택적으로 구성하고 제공된 UIWindowScene 'scene'에 연결합니다.
        // 스토리보드를 사용하는 경우 `window` 속성이 자동으로 초기화되어 장면에 첨부됩니다.
        // 이 대리자는 연결 장면이나 세션이 새롭다는 것을 의미하지 않습니다.
        // scene: 앱에 연결되는 scene object 입니다.
        // session: scene 구성에 대한 세부 정보가 포함된 세션 개체입니다.
        // options: scene 구성을 위한 추가 옵션입니다. 이 개체의 정보를 사용하여 장면을 생성한 작업을 처리한다. 예를 들어 사용자가 선택한 빠른 작업에 응답.
        guard let _ = (scene as? UIWindowScene) else { return }
    }

    func sceneDidDisconnect(_ scene: UIScene) {
        // 시스템에서 장면을 릴리스할 때 호출됩니다. 
        // 이것은 장면이 배경에 들어간 직후 또는 세션이 삭제될 때 발생합니다.
        // 다음에 장면이 연결될 때 다시 만들 수 있는 이 장면과 관련된 모든 리소스를 해제합니다. 
        // 해당 세션이 반드시 폐기되는 것은 아니므로 장면이 나중에 다시 연결될 수 있습니다
    }

    func sceneDidBecomeActive(_ scene: UIScene) {
        // 장면이 비활성 상태에서 활성 상태로 이동할 때 호출됩니다. // 장면이 비활성화되었을 때 일시 중지된(또는 아직 시작되지 않은) 작업을 다시 시작하려면 이 메서드를 사용합니다.
    }

    func sceneWillResignActive(_ scene: UIScene) {
        // 장면이 활성 상태에서 비활성 상태로 이동할 때 호출됩니다. // 일시적인 중단(예: 전화 수신)으로 인해 발생할 수 있습니다.
    }

    func sceneWillEnterForeground(_ scene: UIScene) {
        // 장면이 배경에서 전경으로 전환될 때 호출됩니다. // 이 메서드를 사용하여 배경 입력 시 변경 사항을 취소합니다.
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        // 전경에서 배경으로 장면이 전환될 때 호출됩니다. 
        // 이 메서드를 사용하여 데이터를 저장하고, 공유 리소스를 해제하고, 충분한 장면별 상태 정보를 저장합니다. 
        // 장면을 현재 상태로 되돌립니다.
        (UIApplication.shared.delegate as? AppDelegate)?.saveContext()
    }
}
  • 화면구성을 위해선 scene 메서드를 사용해야 한다.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
  • 그렇다면 window는 무엇일까?

📍 UIWindow

  • 앱의 사용자 인터페이스에 대한 배경과 보기에 이벤트를 전달하는 개체입니다.
  • Windows는 이벤트를 처리하고 앱 작동에 기본적인 다른 많은 작업을 수행하기 위해 뷰 컨트롤러와 함께 작동합니다.
  • UIKit은 대부분의 창 관련 상호 작용을 처리하며 많은 앱 동작을 구현하는 데 필요한 다른 개체와 함께 작동합니다.
  • 다음을 수행해야 하는 경우에 창을 사용합니다.
    • 앱의 콘텐츠를 표시할 기본 창을 제공합니다.
    • 추가 콘텐츠를 표시하려면 추가 창을 만듭니다(필요에 따라).
  • 앱에서 스토리보드를 사용하지 않는 경우 이 창을 직접 만들어야 합니다.
  • method
    • init(windowScene: UIWindowScene)
      window를 만들고 지정된 장면 개체와 연결합니다.
    • var rootViewController: UIViewController?
      window의 최상위 View 컨트롤러입니다..
    • makeKeyAndVisible()
      window를 표시하고 Key window으로 만듭니다.
  • scene 수정해보기
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            guard let windowScene = (scene as? UIWindowScene) else { return }
            window = UIWindow(windowScene: windowScene)
            window?.rootViewController = myNavigationController() // Navigation 방법으로 화면을 구성해야 하니까 최상위를 NavigationController로 설정
            window?.makeKeyAndVisible()
        }
  • makeKeyAndVisible()를 사용해서 화면을 띄어준다고 한다. 그래서 Key Window가 무엇인가 봤더니..

    ???? 넘어가자.

📍 UINavigationController

🔗 첫번째 방법

myNavigationController에서 처리하는 방법
  • 사용 method

    • func pushViewController(UIViewController, animated: Bool)
      뷰 컨트롤러를 수신기의 스택에 푸시하고 디스플레이를 업데이트합니다.
  • NavigationCotroller의 viewDidLoad()에서 메인화면으로 바로 push하는 방법으로 초기화면 접근하기

    class myNavigationController: UINavigationController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let mainViewController = mainViewController()
            self.pushViewController(mainViewController, animated: true)
        }
    }
  • 이 방법도 내가 원하는 초기화면을 띄어주는게 가능했다. 하지만, 뭔가 낭비? 같은 느낌

🔗 두번째 방법

sceneDelegate.swift에서 처리하는 방법
  • 사용한 UINavigationViewController initialize
    - init(rootViewController: UIViewController)
    Initializes and returns a newly created navigation controller.
  • scene 메서드에서 설정하는 방법으로 초기화면 접근하기
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            guard let windowScene = (scene as? UIWindowScene) else { return }
            window = UIWindow(windowScene: windowScene)
            let mainViewController = mainViewController() // 내가 원하는 초기화면
            let navigationController = UINavigationController(rootViewController: mainViewController) // navigationController의 rootViewController를 main으로 설정
            window?.rootViewController = navigationController // window의 rootViewController를 navigationController로 설정
            window?.makeKeyAndVisible()
        }
  • sceneDelegate에서 처리했기 때문에 UINavigationController에 대한 class를 따로 만들지 않아도 된다.
  • rootViewController라는 개념을 앞으로도 많이 사용해야 해야겠다.

📍 후기

  • 시간이 된다면 코드의 이유를 추적하는 습관을 기르면 좋을거 같다. 일단 원리를 조금씩 알아가는 재미가 있고 흐름파악에 많은 도움이 되는 것 같다. 또한, 이유있는 코드를 짜는 개발자가 되는데 많은 도움이 될 것 같다.
  • Key Window는 쓰지도 않을거면서 왜 makeKeyAndVisible 함수를 쓰는건지.... 아시면 댓글 부탁해요

UISceneDelegate
UIWindow
UINavigationController

profile
I Am Groot

0개의 댓글