본문 바로가기
Apple/SwiftUI

[iOS] Apple의 Introducing SwiftUI 공부하기 1

by 어멘드 2023. 7. 25.
반응형

애플 개발자 문서에서 제공하는 튜토리얼인 Introducing SwiftUI를 읽으면서 SwiftUI를 공부해보자.

 

Introducing SwiftUI | Apple Developer Documentation

SwiftUI is a modern way to declare user interfaces for any Apple platform. Create beautiful, dynamic apps faster than ever before.

developer.apple.com

 

 총 4개의 챕터로 이루어져 있고, 각 챕터마다 2-3개의 소챕터가 존재한다. 가장 첫번째 소챕터 Creating and Combining Views부터 시작해보자.

1. SwiftUI Essentials
    a. Creating and Combining Views
    b. Building Lists and Navigation
    c. Handling User Input
2. Drawing and Animation
    a. Drawing Paths and Shapes
    b. Animating Views and Transitions
3. App Design and Layout
    a. Composing Complex Interfaces
    b. Working with UI Controls
4. Framework Integration
    a. Interfacing with UIKit
    b. Creating a watchOS App
    c. Creating a macOS App

 

Section 1

이 튜토리얼은 Landmarks라는 앱을 단계적으로 만들어나가는 내용이라고 한다. 일단 iOS App으로 "Landmarks" 라는 이름의 새 프로젝트를 만들어주었다. 인터페이스를 스토리보드가 아니라 SwiftUI로 설정해주는 것을 잊지 말자. 프로젝트 초기 폴더는 아래와 같이 생성되었다.

 

먼저 LandmarksApp.swift 를 살펴보자. 이것이 전체 앱에 대한 구조체인가보다.

 첫번째, App 프로토콜을 채택하고 있는데, App 프로토콜은 앱의 구조와 행동을 나타내는 타입으로 SwiftUI 앱 라이프사이클을 사용하는 앱은 App 프로토콜을 준수하는 구조이다. 

 두번째, body 프로퍼티는 하나 이상의 Scene을 반환하며 표시할 컨텐츠를 나타낸다. Scene은 사용자에게 표시하고 싶은 뷰 계층 구조의 컨테이너 역할을 한다. 지금 반환하고 있는 WindowGroup이라는 씬에는 ContentView라는 뷰 하나가 들어있는 구조이다. WindowGroup과 같은 내장 씬도 있고, 직접 커스텀 씬을 만들 수도 있다. 

 마지막으로, @main은 앱의 진입점을 식별하는 역할을 한다. 당연히 단 한 개의 진입점만 가질 수 있다. App 프로토콜에는 앱을 초기화하고 실행하는 main() 메소드가 디폴트로 구현되어 있는데, 선언부 앞에 @main 속성이 있는 경우 시스템이 이 main() 메서드를 호출하여 앱을 실행하게 된다.

 

 다음으로 ContentView.swift를 살펴보자.

 코드 에디터 아래에 캔버스가 존재하는 것을 볼 수 있다. 만약 캔버스가 보이지 않는다면 [Editor > Canvas] 를 설정해주자. UIKit 커스텀 뷰를 만드는 경우, xib 방식이 아니면 빌드하여 실행하기 전까지는 작성한 뷰의 결과를 확인할 수 없다. 하지만 SwiftUI는 뷰 코드에 대해 실시간 프리뷰가 가능하다.

 기본적으로 SwiftUI View 파일은 두 개의 구조체를 선언한다. 첫 번째 구조체는 오리지널 View이고, 두 번째 구조체가 프리뷰용 PreviewProvider이다. ContentView의 body를 수정해보자. 기존의 VStack을 제거하고 단일 Text로 교체해주었다.

이제 캔버스를 확인해보면, 다음과 같이 "Hello SwiftUI"로 자동 반영되어 있는 것을 볼 수 있다.

 

Section 2

 이번에는 인스펙터를 사용하여 텍스트를 수정해보자. 캔버스의 왼쪽 하단 두번째 버튼을 눌러 Selectable 모드로 변경하고, cmd 키를 누른 상태에서 텍스트를 클릭하면 메뉴가 뜬다. 또는 코드에디터에서 cmd키를 누르고 Text의 이니셜라이저 부분을 클릭해도 된다. 이제 Show SwiftUI Inspector 메뉴로 들어가면 텍스트를 조작할 수 있는 인스펙터가 열리가 된다. 인스펙터를 사용하여 내용을 Turtle Rock으로, 폰트를 .title로 변경하였더니 코드에도 반영이 되었다. 인스펙터를 사용하여 뷰를 수정해도 코드에 바로 자동 반영이 된다.

 다음으로는 직접 코드를 추가하여 텍스트를 수정해보자. SwiftUI 뷰를 커스텀할 때는 modifiers 메소드를 호출한다. 각 modifier는 새로운 뷰를 반환하므로, 여러 modifier를 체이닝하여 사용하는 것이 일반적이다. 방금 추가된 .font() 또한 modifier에 해당한다. 원형을 보면 이렇게 폰트가 변경된 새 Text를 반환하고 있다.

func font(_ font: Font?) -> Text

 이제 modifier를 사용하여 텍스트의 foreground를 초록색으로 바꿔보자. font가 변경된 텍스트에 색깔까지 변경하는 것이므로 .font() 뒤에 .foreground() modifier를 추가한다. 캔버스를 확인해보면 초록색으로 바뀌어있을 것이다.

 

Section 3

 스택을 사용하여 뷰를 수평/수직으로 결합해보자. UIKit과 마찬가지로 Stack을 사용하면 된다. Vertical Stack View는 VStack, Horizontal Stack View는 HStack이다. Z축 방향으로 겹칠 수 있는 ZStack도 있다.

먼저 Text를 VStack에 넣어보자. 다시 cmd 키를 누른 채로 Text의 이니셜라이저를 클릭, Embed in VStack을 선택하면 다음과 같이 VStack 안에 Text가 들어간다.

이제 VStack에 다른 뷰를 하나 더 넣어서 정말 스택에 뷰들이 잘 쌓이는지 확인해보자. 스토리보드 사용할 때와 마찬가지로 우측 상단의 +버튼을 누르고 Text를 검색, 드래그 앤 드롭하면 간단하게 추가할 수 있다. 폰트도 변경해주자. 프리뷰를 확인해보면 이렇게 TurtleRock 아래에 텍스트가 추가되었다.

VStack의 정렬을 변경해보자. 지금은 디폴트 설정인 가운데 정렬로 되어있는데, 이것을 좌측 정렬로 변경해보자. VStack 이니셜라이저의 alignment 파라미터로 설정가능하다. VStack을 VStack(alignment: .leading)로 변경하고 캔버스를 확인해보면 좌측 정렬이 되어있을 것이다.

다음으로 California라는 새로운 Text를 생성하여 Joshua Tree National Park 우측에 추가해보자. Text("Joshua Tree National Park")를 HStack 안으로 넣고, Text("California")를 새로 추가해주면 되겠다.

그런데 두 텍스트 사이의 거리가 너무 가깝다. 간격을 줘보자. 두 텍스트 사이에 Spacer()를 추가한다. 추가했더니 두 텍스트가 양 끝으로 붙어버렸다. Spacer는 포함된 뷰들이 부모뷰의 모든 공간을 사용하도록 확장된다. Spacer가 스택에 포함된 경우 스택의 축을 따라 확장되고, 스택에 포함되지 않은 경우 모든 축으로 확장된다. 현재 Spacer가 HStack에 포함되어 있기 때문에, 스페이서가 수평으로 확장되어 형제뷰인 두 텍스트가 화면 양 끝까지 밀려나게 된다.

너무 딱 붙는 것이 보기 좋지 않으니 VStack에 패딩을 추가하여 살짝 띄워주자. 전체 코드는 아래와 같다.

 

Section 4

튜토리얼 페이지에서 리소스를 다운받는다. turtlerock@2x 이미지를 찾아 에셋으로 추가해준다. 그리고 CircleImage.swift라는 SwiftUI View 파일을 하나 생성한다.

body에 방금 추가한 이미지로 이미지뷰를 하나 만들자. Image(에셋이름)으로 간단하게 생성할 수 있다.

지금은 사각형 형태이다. 원형으로 바꿔보자. 원하는 모양으로 자를 때는 .clipShape(_:style:)라는 modifier를 사용한다. 첫번째 파라미터로는 원하는 Shape을, 두번째 style 파라미터에는 해당 shape를 채우는 스타일인 FillStyle을 넘겨주면 되는데, 생략할 경우 디폴트 값으로 적용된다. 우리는 원형으로 바꾸어야 하므로 Circle() 이라는 Shape를 생성해서 넘겨주자.

테두리와 그림자도 만들어주자. 테두리는 이미지 위에 회색 원형 스트로크를 .overlay(alignment:content:) 해주고, 그림자는 .shadow(color:radius:x:y:) 모디파이어를 사용한다.

 

Section 5

이번에는 지도를 추가한다. MapView.swift를 하나 만들고 MapKit을 import 한다. 같은 파일에서 SwiftUI와 특정 다른 프레임워크를 가져오면, 해당 프레임워크에서 제공하는 SwiftUI 관련 기능에 액세스할 수 있다.

 MapView에 지역 정보를 담는 @State 프로퍼티 하나를 추가하자. @State 속성은 뷰 계층구조 안에 저장되어 여러 개의 뷰에서 공유할 수 있는 상태값 데이터이다. App, Scene, View 안에 선언 가능하다. SwiftUI가 해당 값을 관리하여 값에 따라 자동으로 뷰를 업데이트해준다.

이제 body 안의 텍스트를 Map으로 변경해주자. Map은 지도 인터페이스를 표시해주는 뷰이다. State 변수 앞에 $를 붙이면, 기본 값에 대한 참조와 같은 바인딩을 전달한다. 따라서 사용자가 뷰를 조작하여 맵에 보이는 지역을 이동하면 region 값도 업데이트 된다.

 

Section 6

ContentView에 MapView와 CircleImage를 추가해주자. 기존의 VStack을 또 다른 VStack으로 감싸고, 맨 위에 MapView와 CircleImage를 추가한다.

각 뷰들의 위치를 조정해주자. offset, padding, .ignoreSafeArea, Spacer를 활용하였다.

텍스트 부분 아래에 분리선과 설명을 추가하고, 부가설명 텍스트의 컬러를 .secondary로 바꾸어주자. 한번에 바꾸기 위해 부가 설명 텍스트들이 묶인 HStack에 적용해주었다. 이렇게 스택에 modifier를 사용하면, 스택 내부의 모든 요소에 적용이 된다.

 

첫 번째 소챕터 Creating and Combining Views를 완료했다. 다음 소챕터는 2탄에서 읽어보자.

 

[iOS] Apple의 Introducing SwiftUI 공부하기 2

1편은 여기에서 확인할 수 있다. [iOS] Apple의 SwiftUI Tutorials 공부하기 1 애플 개발자 문서에서 제공하는 SwiftUI Tutorials를 읽으면서 SwiftUI를 공부해보자. Introducing SwiftUI | Apple Developer Documentation SwiftUI

please-amend.tistory.com

 

반응형

댓글