Skip to content

#2 - SwiftUI 시작하기 #2

Description

@L-j-h-c

2. SwiftUI 시작하기

키워드 : @State @Binding

배운 내용

목표

  • Xcode Canavase를 이용해서 코드와 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를 편하게 만들 수 있다...!

image

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를 이용하여 알러트를 만들 수 있다.

image

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!"))
    )
}
질문
  1. App Protocol은 무슨 역할을 하고 어떻게 사용할 수 있을까? 앱 전반에 사용되는 State를 전달하면 어떻게 사용할 수 있을까?
  2. @State@binding의 차이는 무엇일까?
  3. @ViewBuilder는 SwiftUI에서 어떤 역할을 할까?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions