[SwiftUI] 2. 앱 원칙: Scene를 사용한 view 의 계층 구조 지정

Sean·2023년 5월 3일
0

SwiftUI_튜토리얼

목록 보기
2/11

참고 자료: SwiftUI 튜토리얼 공식문서

이제 막 SwiftUI를 배워보는 한 사람으로서, 코드 작성하고 내가 이해 한 대로 작성할것이다.

이 글의 내용은 위에 있는 참고자료의 공식문서를 번역하여 조금 더 내가 느끼기에 자연스럽게 만들어서 작성하는것이다.

누군가에게 알려주기보다 자신이 정리를 하면서 다시 문서를 보고 어버버거리지 않게 다시 참고하기 위함이기에 해당 문서를 읽는 사람은 swift에 대해서 어느 정도 안다는 가정하에 글을 작성할것이다

시작

Scene에는 앱의 view 계층 구조가 포함 되어있다.
SwiftUI는 앱의 사용자 인터페이스를 만드는데 도움이 되는 빌딩 블록을 제공한다.
이러한 블록 중 하나인 Scene는 앱의 사용자 인터페이스를 정의하는 view 계층 구조를 포함한다.
Scene로 SwiftUI에서 제공하는 앱의 보기 계층을 지정하거나, 사용자 정의 계층을 만들 수 있다.

Sample code

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            TabView {
                ContentView()
                    .tabItem {
                        Label("Journal", systemImage: "book")
                    }
                SettingsView()
                    .tabItem {
                        Label("Settings", systemImage: "gear")
                    }
            }
        }
    }
}

분석

1. 앱에 Scene 추가하기

SwiftUI에는 단하나의 진입점과 앱 구조체가 존재한다.

MyApp 구조체에 Scene를 반환하는 연산프로퍼티 body를 구현한다.
body는 하나 이상의 기본 및 보조 Scene를 반환할 수 있다.

WindowGroup Scene는 가장 일반적으로 사용되는 Scene 중 하나이다.
macOS 및 iPadOS에서 여러 창을 지원하는 등 앱의 플랫폼별 동작을 제공한다.

view 계층 구조의 root node 는 TabView이다. 사용자가 다른 하위 view간 전환에 사용할 수 있는 탭을 제공한다.
Struct: TabView

2. 다른 View 계층구조 정의

앞의 샘플은 macOS에서는 제대로 보이지 않기에 Mac고유 기능을 활용하는 다른 view 계층 구조를 선언한다.

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        #if os(iOS)
        WindowGroup {
            TabView {
                ContentView()
                    .tabItem {
                        Label("Journal", systemImage: "book")
                    }
                
                SettingsView()
                    .tabItem {
                        Label("Settings", systemImage: "gear")
                    }
            }
        }
HERE >>>         
		#elseif os(macOS)
        WindowGroup {
            AlternativeContentView()
        }
        
        Settings {
            SettingsView()
        }
        #endif
    }
}

이전의 iOS 와는 다르게 사용자 정의 View 계층 구조이다. : AlternativeContentView()

맥 앱의 일반적인 기능 중 하나인 앱 메뉴에서 사용 가능한 Settings 메뉴 항목을 제공하기 위해 보조 Scene인 Settings Scene를 사용한다.
Setting Scene 는 macOS에서만 사용이 가능하다.

Setting Scene에는 커스텀 view가 포함되어있다.
Setting 메뉴항목이 존재하는 창에서 앱설정을 표시한다.
Struct: Settings

두 개의 view 계층 구조가 정의된 경우 대상 플랫폼에 따라 사용할 계층 구조를 지정해야 한다.

#if 의 조건을 사용하여 첫번째 View 계층 구조를 iOS 전용 컴파일 하며 두번째 계층 구조에서는 macOS 전용으로 컴파일을 한다.

3. 커스텀 Scene 만들기

위의 코드는 다양한 버전의 view 계층 구조를 정의하지만 코드가 길어 유지보수에 문제가 있을 수 있다.
코드를 읽기 쉽고 관리하기 쉽게 만들기 위해서는 Scene를 커스텀 해서 사용하는것이 도움이 된다.

MyScene.swift

import SwiftUI

struct MyScene: Scene {
    var body: some Scene {
        WindowGroup {
            TabView {
                ContentView()
                    .tabItem {
                        Label("Journal", systemImage: "book")
                    }
                
                SettingsView()
                    .tabItem {
                        Label("Settings", systemImage: "gear")
                    }
            }
        }
    }
}

Scene 프로토콜을 준수하는 구조체를 선언하고 Scene 프로토콜을 준수하는 만큼 body 연산 프로퍼티를 구현한다.
Protocol: Scene

MyAlternativeScene.swift

import SwiftUI

struct MyAlternativeScene: Scene {
    var body: some Scene {
        WindowGroup {
            AlternativeContentView()
        }
        
        #if os(macOS)
        Settings {
            SettingsView()
        }
        #endif
    }

macOS의 경우에 사용할 또 다른 커스텀 구조이다
Settings는 macOS에서만 사용 가능하다.

4. 커스텀 Scene를 사용하도록 코드 리팩토링하기

커스텀 Scene 사용하여 구조를 리팩토링 하기 전에는 코드가 길고 복잡하다
그러나 리팩토링 후의 구조는 읽고 관리하기가 더 쉽다.

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        #if os(iOS)
        MyScene()
        #elseif os(macOS)
        MyAlternativeScene()
        #endif
    }
}

참고자료

Protocol: Scene

Struct: TabView
Struct: Settings

기타

당연 틀린 부분 지적은 감사하나 비난은 정중하게 사양하겠다.

profile
"잘 할 수 있을까?"를 고민하기보단 재밌어 보이는건 일단 하고, 잘하기 위해 그냥 계속합니다.

0개의 댓글