[iOS] storyboard 가 아닌 코드로 UI 구현하기 - Navigation Controller

Youngwoo Lee·2021년 3월 20일
0

iOS

목록 보기
2/46
post-thumbnail

Develop iOS without Storyboard


Storyboard에서는 간편하게 Editor-Embed in-Navigation Controller로 추가하였는데

평소에 코드를 통한 개발에도 관심이 많아서 코드로 Navigation Controller을 추가해보려고 합니다. 해당 글은 학습을 기록하기 위한 글입니다

참고 ) 해당 글은 리나님의 글을 참고했습니다


Remove Main.storyboard

가장 먼저 Main.storyboard 파일을 삭제합니다
삭제할 때는 move to trash

완전하게 삭제합니다. 참조만 삭제할 경우에는 나중에 문제가 생기는 경우가 많습니다

그리고 바로 Info.plist 파일로 이동합니다



Info.plist 설정 변경

Main storyboard file base name - Main
해당 항목을 찾아서 완전히 삭제! 해줍니다

그리고 Application Scene Manifest - Scene Configuration - Application Session Role - Item 0 - Storyboard Name 항목 또한 삭제해준다!

그리고 Build를 하게 되면??

아무것도 안뜨게 된다ㅎㅎ 이제 mainStoryboard의 흔적을 완전히 지웠으니 한번 코드로 작성해 보자!!



SceneDelegate.swift로 이동!

SceneDelegate는 UILifeCycle 역할을 맡고 있는 부분이다!
관련 내용은 해당링크를 보고 익혀보자!! 꼭! 애플동영상, 블로그 정리

iOS 13버전 미만에서는 SceneDelegate가 없었다고 한다.


다시 돌아와서, 일단 func scene(scene: session: option:) 함수를 보자!
parameters

  • scene: 앱에 연결중인 scene 객체
  • session: 장면 구성에 대한 세부 정보가 들어 있는 session 개체
  • options: scene을 구성하기 위한 추가 옵션이다. 이 개체의 정보를 사용하여 씬(scene)을 만든 액션을 처리한다.

Discussion
이 메서드는 앱이 사용자 인터페이스의 인스턴스를 생성하거나 복원할 때 호출된다. 사용자 또는 앱이 사용자 인터페이스의 새 인스턴스를 요청할 때 UIKit은 적절한 장면 개체를 만들어 앱에 연결한다. 이 메서드를 사용하여 새로운 scene의 추가에 대응하고, scene이 표시해야 하는 모든 데이터 로드를 시작할 수 있다.

여튼 자세히는 모르겠지만, 새로운 scene이 시작할 때 화면에 표시하고 싶은 데이터를 이 함수에서 구현하면 될거 같다

기존에 있던 guard let _ = (scene as? UISWindowScene) else { return } 변수에 이름을 주자

그리고 아래와 같이 코드를 작성한다

guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let mainViewController = ViewController()

window?.rootViewController = mainViewController
window?.makeKeyAndVisible()

UIWindow

  • 앱의 user Interface 배경, 그리고 view에 이벤트를 보내는 개체

  • 다음을 수행해야 하는 경우에만 window을 사용한다
    - 기본 window을 제공하여 앱의 콘텐츠를 표시한다
    - 필요에 따라 추가 window을 만들어 추가 내용을 표시한다

일반적으로 Xcode는 앱의 기본 window를 제공한다. 새로운 iOS 프로젝트는 스토리보드를 사용하여 앱의 view를 정의한다. 스토리보드는 Xcode 템플릿이 자동으로 제공하는 AppDeleage 개체에 window 속성이 있어야 한다. 앱에서 스토리보드를 사용하지 않는 경우 이 window를 직접 만들어야 한다

터치 이벤트가 발생한 창으로 전달되는 반면, 관련 좌표 값이 없는 이벤트는 키 창으로 전달됩니다. 한 번에 하나의 창만 키 창이 될 수 있으며 창의 isKeyWindow 속성을 사용하여 상태를 확인할 수 있습니다. 대부분의 경우 앱의 기본 창이 키 창이지만 UIK는 필요에 따라 다른 창을 지정할 수 있습니다.


windowScene - Instance Property

  • windowScene = window를 포함하는 Scene이다
  • 이 속성 값을 변경하면 창이 새로 지정된 Scene으로 이동한다. 속성을 0으로 설정하면 창이 현재 장면에서 제거된다



ViewController에 화면 구성

ViewController의 상위 View에 backgroundColor 값을 설정하지 않으면 검은색 화면만 계속해서 나올 것이다.

let test = UILabel()
view.backgroundColor = .white
view.addSubview(test)
test.text = "text"
test.translatesAutoresizingMaskIntoconstraints = false
test.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
test.centerYAnchor.constraint(equalTo: view


SceneDelegate에 NavigationController 추가

그리고 이후 NavigationController 추가를 위해 다시 sceneDelegate로 이동

guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let mainViewController = ViewController()
let navigationController = UINavigationController(rootViewController: mainViewController)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()

makeKeyAndVisible

창을 표시하고 Key window로 만든다

Discussion
이 method는 현재 window를 표시하고 같은 수준 이하의 다른 모든 window 앞에 배치하는 편리한 방법이다. window만 표시하려면 hidden property를 No로 변경합니다.

key window: 터치 관련된 이벤트가 아닌 이벤트나, 키보드 이벤트 등을 받고 있는 윈도우. 한 시점에 하나의 윈도우만 키 윈도우이다
참고자료) https://seizze.github.io/2019/11/21/iOS의-Window에-대해.html



이후 Viewcontroller의 viewDidLoad에서 다음 코드까지 추가하면 완성!

self.navigationItem.title = "Kane's Navigation"



아직 SceneDelegate의 구동방식이 완벽하게 이해되지는 않지만, 조금 더 자료를 찾아가며 채우면 코드로 진행하는 방식이 익숙해질 것 같다.

와우 글 작성하고 나서 캠퍼의 TIL 에서 추천 링크를 보고 AppDelegate와 SceneDelegate를 보니 모든 궁금증이 해소되었다...
https://velog.io/@yongchul/iOSView의-형성과정 👍🏼👍🏼👍🏼
https://velog.io/@dev-lena/iOS-AppDelegate와-SceneDelegate 👍🏼👍🏼👍🏼

profile
iOS Developer Student

1개의 댓글

comment-user-thumbnail
2021년 6월 9일

잘 봤읍니다.... ~^~^~

답글 달기