---
# System prepended metadata

title: SwiftUI PropertyWrapper
tags: [Swift, SwiftUI, iOS]

---

###### tags: `iOS` `Swift` `SwiftUI`
# SwiftUI PropertyWrapper
PropertyWrapper (屬性包裝器)是 Swift 5.1 引入的新功能
它的目的就是封裝一個屬性的特性，並對類似的屬性做修飾，使其實現相同的代碼

```kotlin=
struct ContentView: View {
    var body: some View {
        Text(Data(title: "abc").title)
    }
}

@propertyWrapper
struct Uppercased {
    private var value: String = ""

    //@propertyWrapper 必須實作 wrappedValue
    var wrappedValue: String {
        set { value = newValue.uppercased() }
        get { value }
    }

    init(wrappedValue: String) {
        self.wrappedValue = wrappedValue
    }
}

struct Data {
    @Uppercased var title: String
}
```

首先定義一個 @propertyWrapper 的結構，而 propertyWrapper 必須實作 wrappedValue
當操作要包裹的屬性時，其具體的 set、get 方法，就是 wrappedValue 的 set、get
接著定義一個 Data 結構，並使其屬性 title 被包裝，這樣一來在使用 Data 的 title 就會進行被包裝的行為
此範例就是將此屬性轉換為大寫

## @State
使用在 struct 內部，通常會用 private 修飾
用途：在struct內可以修改變數值、當變數值被修改時，更新畫面

## @Binding
使用在外部傳遞，可將數值型態轉為參考型態
用途：在外部傳遞資料

## @EnviromentObject
當被修飾的變數改變時，通知其使用的地方進行更新，如同觀察者模式
用途：用於需要經常通知的情況，搭配 ObservableObject 使用

## @ObservedObject
當被修飾的變數改變時，通知其使用的地方進行更新，如同觀察者模式
用途：用於需要通知的情況，搭配 ObservableObject 使用

## @Enviroment
監聽系統級別的東西
用途：系統級別的操作就必須使用它

[使用 @propertyWrapper 讓代碼更簡潔](https://www.jianshu.com/p/ff4c048f0cf4)
[PropertyWrapper屬性包裝器](http://aiur3908.blogspot.com/2019/08/ios-propertywrapper.html)
[理解 SwiftUI @State, @Binding, @ObservedObject, @EnvironmentObject](https://juejin.im/post/5d625c01f265da03cd0a8a58)
