---
# System prepended metadata

title: Swift UI Prperty Wraaper

---

# Swift UI Prperty Wraaper

## @State
-  개체 내부에서 사용되며 뷰 View가 에 대한 변경 사항에 응답할 수 있도록함
-  뷰가 포함된 뷰가 소유한 속성에 대해 사용
-  뷰는 @State속성 자체를 초기화
-  다른 개체에서 속성을 받지 않음
-  뷰 자체에 의해 관리되는 상태에 적합
-  새로 고침 중에 뷰 인스턴스를 삭제하고 다시 생성해야 할 때 유지되어야 함
-  private을 사용하는 것이 일반적이며, 외부 소스가 @State속성을 수정해서는 안됨
### @State를 사용하는 경우
- View자체에서 wrapping할 인스턴스를 만들고 소유해야 할 때
- wrapping된 인스턴스 내에서 발생하는 변경사항에 대항해야 할 때
- 값을 wrapping 할 때

## @Binding
- 다른 View에서 전달된 Property를 사용할 때
- 바인딩을 받는 뷰는 바인딩된 Property를 읽고 외부 소스(예: 상위 뷰)의 변경 사항에 응답할 수 있으며 속성에 대한 쓰기 액세스 권한이 있음
- @Binding을 업데이트하면 제공한 뷰의 해당 Property가 업데이트 된다는 의미
### @Binding을 사용하는 경우
- 상위 뷰가 소유한 Property에 대한 읽기 및 쓰기 액세스 권한이 필요할 때

## @StateObject
- 참조 유형이며, Property 중 하나가 변경될 때마다 Swift UI에 알림
- State + ObservedObject 느낌
### @StateObject를 사용하는 경우
- Property의 변경 또는 업데이트에 응답하려고 할 때

## @ObservedObject
- 사용되는 뷰에서 생성하거나 소유하지 않은 인스턴스를 래핑하는데 사용 (ObservableObject)
- @StateObject의 기능과 거의 유사
- 대부분 ViewModel을 선언할 때 사용하는 프로퍼티래퍼
- ViewModel에서 변경사항이 있다면 뷰를 다시 그릴수 있도록 해주는 역할

### @ObservedObject을 사용하는 경우
- Property의 변경 또는 업데이트에 응답하려고 할 때

## @EnvironmentObject
- 같은 오브젝트를 여러 곳에서 사용할 때

## @StateObject와 @ObservedObject의 차이는 무엇인가요?
- ObservedObject는 값의 변화가 있을 때, View 전체를 다시 그리고, StateObject는 변화된 값이 있는 View만 다시 그립니다. 따라서 ObservedObject는 View Life Cycle의 영향을 받고, StateObject는 View Life Cycle의 영향을 받지 않습니다.

### 출처
[SwiftUI Property Wrapper](https://swiftuipropertywrappers.com/)


---

SwiftUI Property Wrapper 정리

### @State

> A property wrapper type that can read and write a value managed by SwiftUI.

해당 변수의 값이 바뀌면, SwiftUI가 View를 자동으로 업데이트 함

### @Binding

> A property wrapper type that can read and write a value owned by a source of truth.

View간의 양방향 바인딩을 위해 사용

ex)

```swift
struct MainView: View {
  @State private var isPlay = false
  
  var body: some View {
    VStack(spacing: 20) {
      PlayButton(isPlaying: $isPlay)
      
      Button(isPlay ? "재생중" : "정지중") {
        isPlay.toggle()
      }
      .buttonStyle(.borderedProminent)
    }
  }
}

struct PlayButton: View {
  @Binding var isPlaying: Bool
  
  var body: some View {
    Image(systemName: isPlaying ? "play.fill" : "pause.fill")
      .resizable()
      .foregroundColor(isPlaying ? .red : .black)
      .frame(width: 100, height: 100)
      .animation(.default, value: isPlaying)
      .onTapGesture {
        isPlaying.toggle()
      }
  }
}
```

### @Published

> A type that publishes a property marked with an attribute.

### @ObservableObject

> A type of object with a publisher that emits before the object has changed.

object가 바뀌면, 값을 방출한다

### @ObservedObject

> A property wrapper type that subscribes to an observable object and invalidates a view whenever the observable object changes.

observable object를 구독하고있고, observable object가 바뀌면 view를 업데이트 한다

```swift
import SwiftUI

final class MainViewModel: ObservableObject {
  @Published var state: Bool = false
}

struct MainView_ViewModel: View {
  @ObservedObject var viewModel: MainViewModel
  
  var body: some View {
    PlayButton(isPlaying: $viewModel.state)
  }
}
```

### @StateObject

> A property wrapper type that instantiates an observable object.

### @EnvironmentObject

> A property wrapper type for an observable object supplied by a parent or ancestor view.

parent나 더 위의 parent들의 데이터를 공유할 수 있게 해줌

```swift
struct MainView_EnvironmentObject: View {
  @EnvironmentObject var viewModel: MainViewModel
  
  var body: some View {
    VStack(spacing: 32) {
      PlayButton(isPlaying: $viewModel.state)
      ChildView()
    }
  }
}

struct ChildView: View {
  @EnvironmentObject var viewModel: MainViewModel
  
  var body: some View {
    PlayButton(isPlaying: $viewModel.state)
  }
}
```

### @Environment

> A property wrapper that reads a value from a view’s environment.

view의 상태를 알 수 있게 하는 값