본문 바로가기

iOS/SwiftUI

[SwiftUI 기초] SwiftUI 맛보기

목표

  • Xcode Canavas를 이용해서 코드와 UI를 동시에 보며 작업하는 방법 알아보기
  • 재사용 가능한 뷰 만드는 방법 알아보기
  • @State 키워드에 대해 알아보기
  • Alert 띄우기

내용

1. App Protocol을 따르는 struct를 정의하여 App을 시작할 수 있다.

@main
struct RGBullsEyeApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView(guess: RGB())
    }
  }
}

App Protocol의 기본적인 구조는 아래와 같다.

연관 타입으로 Scene을 정의해주고, body를 구현하면 된다.
@SceneBuilder와 같은 어트리뷰트는 추후에 공부해보자.
위의 코드를 보면 WindowGroup을 통해 시작할 Window를 만들어준다.

@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
public protocol App {
    associatedtype Body : Scene
    @SceneBuilder @MainActor var body: Self.Body { get }
    @MainActor init()
}

2. ContentView를 살펴보자.

아래와 같이 View Protocol을 따르는 연산 프로퍼티 body를 구현해주면 되는데
몇 줄의 코드로 텍스트가 중심에 위치한 뷰를 만들 수 있다.

struct ContentView: View {
  var body: some View {
    Text("Hello, world!")
      .padding()
    }
  }
}

3. PreviewProvider란?

PreviewProvider 프로토콜을 따르는 구조체를 선언해서 Xcode Preview를 볼 수 있다.
previews 연산 프로퍼티에 보고 싶은 view를 반환시켜주면 된다.

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(model: Model())
    }
}
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
@MainActor public protocol PreviewProvider : _PreviewProvider {
    associatedtype Previews : View
    @ViewBuilder @MainActor static var previews: Self.Previews { get }
    @MainActor static var platform: PreviewPlatform? { get }
}

Resume을 눌러서 프리뷰를 재생할 수 있다.
Resume 단축키 : option + command + p

4. 다양한 기능 및 단축키

  1. 캔버스에서 cmd+ click을 통해 View들을 조정할 수 있다. Vstack, Zstack 등의 Stack 안으로 embed하거나 Group을 만드는 것이 가능하다.
  2. 코드에 ctrl + option+ click을 통해 View의 Property를 조정할 수 있다.
  3. 상단 툴바의 + 버튼을 눌러서 원하는 Object를 Canvas에 직접 추가할 수 있다, option + click으로 라이브러리를 유지할 수 있다.

5. @State를 통해 프로퍼티의 변경된 값을 UI에 즉시 반영하자.

@State 어트리뷰트를 명시한 Properties의 값이 바뀌면
-> UI는 appearance를 invalidates하고, body를 다시 계산한다.

일반적인 프로퍼티와 마찬가지로 정의 시 초기화하거나, 생성자 주입을 할 수 있다.
생성자 주입을 할 경우 프로퍼티의 타입만 명시해줘도 자동으로 생성자를 만들어준다.

$를 붙여서 변화하는 값을 참조할 수 있다.

struct ContentView: View {
    @State var model: Model
    var body: some View {
            HStack {
                Text("0")
                Slider(value: $model.colorScale)
                    .accentColor(.red)
                Text("255")
            }
    }
}

6. 재사용 가능한 View를 만들어 보자.

원하는 View를 Command+click하면 아래와 같은 옵션들을 볼 수 있다.
Extract Subview를 통해서 SubView를 편하게 만들 수 있다...!

7. Binding

위의 코드를 extract하면 SubView가 추출되는데 이전과 같이 변화하는 값을 참조하기 위해서는,
@binding property와 trackColor를 추가하여 파라미터로 전달하면 된다.

@binding의 의미는 값을 소유하는 것이 아니라 단지 받는다는 것이다. 부모로부터 @State의 변화하는 값을 받을 수 있다.

struct ExtractedView: View {
    @Binding var value: Double
    var trackColor: Color
    
    var body: some View {
        HStack {
            Text("0")
            Slider(value: $value)
                .accentColor(trackColor)
            Text("255")
        }
    }
}

8. Button

버튼은 아래와 같이 "탭하세요"라는 타이틀과 액션을 가지도록 작성할 수 있다.

Button("탭하세요") {
    print("버튼 액션")
}

또한 alert modifier를 이용하여 알러트를 만들 수 있다.

Button("탭하세요") {
    print("버튼 액션")
    guess.high = true
}
.alert("알러트 제목",
       isPresented: $showAlert) {
    Button("확인", role: .cancel) {
        print("확인 탭 액션"
    }
}

아래와 같이 Alert 구조체를 이용할 수도 있다.

Button("탭 액션") {
    showAlert = true
}
.alert(isPresented: $showAlert) {
    Alert(
        title: Text("알러트 제목"),
        message: Text("알러트 메시지"),
        dismissButton: .default(Text("Got it!"))
    )
}