본 포스팅은 Swift 5.2.4 기준으로 작성되었습니다.
SwiftUI 에서 사용자가 확인할 화면을 생성하는 것은 UIKit 과 다르게 확연히 간단해졌습니다.
첫 눈에 바로 들어오는 특징으로는 인스턴스를 생성 시에 더 이상 UI 접두사를 붙이지 않아도 된다는 것이네요. 그리고 내부적으로 바뀐 큰 차이점은 UIKit 의 인스턴스들은 대부분 class 형태로 구성되어있던 것과 다르게 SwiftUI 의 인스턴스들은 대부분 struct 형태로 구현되어있습니다.
그럼 프로젝트를 생성하고 달라진 점들을 직접 살펴보는 것이 좋겠어요. 프로젝트 생성 시 User Interface 를 SwiftUI 로 설정하고 시작하게 되면 다음과 같은 화면이 보입니다.
우측 상단에 위치한 Resume 버튼을 누르거나 Command + Option + P 를 누르면 SwiftUI 의 핵심기능 중 하나인 Preview 를 활성화 시킬 수 있습니다. 활성화가 정상적으로 되었다면 아이폰 화면 위에 “Hello World” 가 출력된 것을 볼 수 있습니다. 놀랍지 않나요?
기존 Storyboard 처럼 단순히 Layout 을 생성 및 확인하는 것뿐만 아니라 실시간으로 코드와 반응하며 UI 가 변화합니다. 다음 포스트에서 함께 보겠지만 심지어 버튼을 눌러 Print 까지 출력이 가능합니다. Wow
View
그럼 이제 코드를 한번 살펴볼게요.
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, World!")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
UIKit 과 달라도 너무 다르네요. 하지만 저는 위에서 본 Preview 의 성능에 감동을 받은 상태이니 새로운 것을 배울 마음의 준비가 되었습니다. 첫 줄을 보면 ContentView 는 View 를 상속받고 있습니다. 왠지 UIView 와 익숙할 것 같지만 혹시 모르니까 무엇인지 한번 알아보도록 하죠.
불과 3개월 전 처음 iOS 개발을 배우기 시작했을 때는 이 문서 보는게 정말 싫었습니다. 봐도 뭐가 뭔지 모르겠고 그냥 다른 블로그 찾아보는게 더 빠르고 쉬웠었거든요. 물론 지금도 이 문서 읽는 것만으로는 사용법을 완전히 익히기에는 부족하지만 그래도 모르는 것이 나타나면 일단 무조건 공식문서부터 찾아보는 습관을 들이고 있습니다. 계속 익숙해지려고 노력하니 조금씩 문서의 구성이나 읽는 방법을 알아가는 것 같아요. 좋은 iOS 개발자가 되려면 그 무엇보다 이 화면과 친해져야 할 것 같아요.
아무튼!! 충격적인게 View 가 Class 도 아니고 Struct 도 아닌 Protocol 이었어요. 아니 어떻게 Protocol 을 저런식으로 사용하지? 근데 또 곰곰히 생각해보면 ContentView 가 Struct 잖아요? 그럼 상속을 받지 못하는게 당연하니 Protocol 일 수 밖에 없었네요. UIKit 의 사용법에만 익숙한 상태라 생소하지만 아무튼 View 는 Protocol 이에요.
Protocol 을 채택했다는건 무언가 필수로 구현해야하는게 있을 수도 있다는 소리잖아요? 그게 바로 저 body 부분입니다. body 부분은 computed property 의 형태로 되어있고 some View 타입을 return 받아야 한다고 알려주고 있어요. 지금 당장 some View 가 무엇인지 전부 파헤치기는 어려우니 뭐가 되었든 View 의 종류들이면 다 괜찮아라고 이해하고 넘어갈게요.
body 의 return 값이 View 의 종류라면 괜찮다고 했는데 Text(“Hello World”) 부분이 오류가 나지않고 정상적으로 Preview 에 표시되었으니까 Text 도 View 의 일종이라는 것입니다. 확실하지 않으니까 이번에도 개발자 문서를 한번 보고 넘어가볼게요.
좌측 상단을 잘 보시면 Views and Controls 라고 적혀있죠? 즉 Text 는 View 나 Control 중 하나라는 뜻입니다. 그리고 설명을 보면 “A view that displays one or more lines of read-only text” 라고 명시하고 있습니다. 읽기 전용으로 쓸 수 있는 텍스트를 표시하는 View 라고 하네요. 상속을 받지도 Protocol 을 채택한 것도 아닌 것이 어떻게 View 로 구분될 수 있는건지는 잘 모르겠지만 공식 문서에서 View 라고 하니 일단 그렇게 알고 넘어가도록 합시다.
PreviewProvider
이제 두번째 문단을 살펴보도록 할게요.
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
또 생소한 것들 투성입니다. 뭔지 모르겠으니까 제일 먼저 등장하는 PreviewProvider 를 찾아봅시다.
이번에도 Protocol 입니다. 어느새 조금 당연해졌죠??
Xcode 에서 previews 를 생성하는 타입이라고 하네요. 정확히는 모르겠지만 우측의 Preview 에 관여하는 코드인 것은 확실합니다. 하지만 이것만으로는 조금 부족한 것 같으니까 PreviewProvider 가 어떤 방식으로 만들어진건지 내부 코드를 봐야할 것 같아요.
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol PreviewProvider : _PreviewProvider {
/// The type of the previews variable.
associatedtype Previews : View
/// Generates a collection of previews.
///
/// Example:
///
/// struct MyPreviews : PreviewProvider {
/// static var previews: some View {
/// return Group {
/// GreetingView("Hello"),
/// GreetingView("Guten Tag"),
///
/// ForEach(otherGreetings, id: \.self) {
/// GreetingView($0)
/// }
/// }
/// .previewDevice("iPhone X")
/// }
/// }
static var previews: Self.Previews { get }
/// Returns which platform to run the provider on.
///
/// When `nil`, Xcode infers the platform based on the file the
/// `PreviewProvider` is defined in. This should only be provided when the
/// file is in targets that support multiple platforms.
static var platform: PreviewPlatform? { get }
}
Property 로 previews 와 platform 을 갖고 있어요. 오늘은 충분히 많은 새로운 내용을 배웠으니 platform 은 다음에 알아보는 것으로 하고 이번에는 previews 만 살펴보도록 할게요. 사용 예시가 나와있네요.
Group 으로 View 들을 묶어 여러개를 표시할 수도 있고 .previewDevice modifier 를 사용해 표시되는 기기를 바꿔줄 수 도 있나봅니다. 이곳에 나와있지는 않지만 여러개의 previews 를 만들어 놓고 하나는 light 다른 하나는 dark 모드로 UI 를 확인해가며 작업하는 것도 가능합니다.
이렇게 SwiftUI 를 시작하는데 있어 가장 기초적인 부분들을 훑어보았는데요. 다음 포스트에서는 SwiftUI 에 여러가지 View 를 추가하는 방법을 알아보도록 하겠습니다.