빙수왕의 개발일지

앱만들기 #2 - 스토리보드 삭제하기 본문

개발/iOS

앱만들기 #2 - 스토리보드 삭제하기

빙수킹 2021. 8. 15. 17:28

스토리보드만의, 앱의 흐름을 한눈에 볼 수 있다는 장점이 있고..

내가 만들 앱의 규모가 크지 않아서 편하게 만들기에는 스토리보드를 써도 무관할 것 같지만,

사람 일은 모르기도 하고, 개인적으로는 코드로 UI를 구성하는게 유지보수측면에서 더 낫다고 생각해서 코드로 하기로 했다.

그리고 코드로 만드는 연습을 좀 하고싶었음!!

 

그래서 두번째로 한 일은 스토리보드를 삭제하는 것이다.

 

스토리 보드를 지우기 위해서는, 아래 과정이 필요하다.

1. storyboard파일을 지우고 Info.plist에 main으로 검색해서 나오는 항목 2개를 지운다.

2. AppDelegate 또는 SceneDelegate에서 window를 만들어주고, window의 rootViewController을 세팅해주고, 만든 window를 keyWindow로 세팅해준다.

 

난 예전에 iOS Deployment Target을 12정도로 했었기에, storyboard파일을 지우면서 동시에 SceneDelegate도 지워버리는게 일반적인 과정이였다.

그리고 AppDelegate에 아래 코드를 추가하곤 했다.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = ViewController()
    window?.makeKeyAndVisible()
    return true
}

 

하지만 이번에는 SceneDelegate를 사용하기로 했기 때문에 SceneDelegate에서 해당 내용을 작성해주어야 했다.

요렇게.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(frame: windowScene.coordinateSpace.bounds)
    window?.windowScene = windowScene
    window?.rootViewController = ViewController()
    window?.makeKeyAndVisible()
}

 

그리고 여기서 궁금한 점들 몇가지를 찾아봤다..

 

1. 일단 이 메소드의 사용처?

 

기본 주석에 따르면,

이 메소드는 UIWindow 객체인 window를 제공된 UIWindowScene 객체인 scene에 연결하고 설정하기 위해 사용한다.

만약 스토리보드를 사용하면, window는 자동으로 초기화되고, scene에 붙는다.

→ 그러니까, 내가 원하는 window를 설정해서 scene에 붙이려면 이 메소드에서 뭔가 설정을 해줘야 한다는 뜻!!!

 

2. windowScene.coordinateSpace.bounds는 무엇인가?

 

coordinateSpace란? scene이 차지하는 좌표 공간이다.

이건 UICoordinateSpace란 protocol의 객체인데, 보니까 이 UICoordinateSpace는 bounds(CGRect)를 프로퍼티로 가지고, convert 메소드를 통해 CGPoint를 CGRect로, CGRect를 CGPoint로 바꿀 수 있는 녀석이다. (아래 사진 참고)

그러니까 windowScene.coordinateSpace.bounds는 쉽게 말해서 windowScene의 bounds이다. 그냥 나중에 point형태로 쉽게 변경하기 위해서 coordinateSpace라는 프로퍼티 안에 넣어놓은 것이다.

 

* 그럼 UICoordinateSpace는 무엇이냐?

서로 다른 기준 프레임간에 변환하는 방법 집합

대충 UIView들이 이걸 통해 서로간의 좌표공간(coordinate space)을 쉽게 변환할 수 있어서 이걸 채택하고 있다는 내용이다.

 

3. window.windowScene = windowScene은 뭐냐?

 

기본적으로 scene은 window를 소유하는 구조이다.

그런데 왜 window에 scene을 프로퍼티로 넣어주나???

 

windowScene은 UIWindow의 인스턴스 프로퍼티다. 이 윈도우가 어느 Scene에 포함되는지를 나타낸다.

이걸 변경하면 윈도우가 새로 지정된 Scene으로 이동한다. 여기 nil을 넣으면 scene에서 윈도우가 제거된다.