Property Wrappers
속성에 적용되는 래퍼(Wrapper)로, 속성의 값에 추가적인 로직을 적용하거나, 값이 변경될 때 다른 동작을 수행할 수 있도록 해준다.
이로 인해 코드의 중복을 줄이고, 속성의 동작을 보다 명확하게 정의할 수 있습니다.
@State
SwiftUI 뷰 내부에서 상태를 관리하는 데 사용됩니다. 상태 변수가 변경되면 해당 상태를 사용하는 뷰가 다시 그려집니다.
@State는 뷰의 로컬 상태를 관리하는 데 적합하며, 외부 객체가 필요하지 않은 경우 사용됩니다.
import SwiftUI
struct CounterView: View {
@State private var count: Int = 0
var body: some View {
VStack {
Text("Count: \(count)")
Button(action: {
count += 1
}) {
Text("Increment")
}
}
}
}
@Binding
@Binding은 SwiftUI에서 상위 뷰의 상태를 하위 뷰에 전달할 때 사용됩니다.
상위 뷰의 상태를 하위 뷰에서 읽고 쓸 수 있게 합니다. 이를 통해 하위 뷰가 상위 뷰의 상태를 직접 수정할 수 있습니다.
상위 뷰:
import SwiftUI
struct ParentView: View {
@State private var isOn: Bool = false
var body: some View {
VStack {
ToggleView(isOn: $isOn)
Text(isOn ? "Switch is ON" : "Switch is OFF")
}
}
}
하위 뷰:
import SwiftUI
struct ToggleView: View {
@Binding var isOn: Bool
var body: some View {
Toggle(isOn: $isOn) {
Text("Switch")
}
.padding()
}
}
@ObservedObject
@ObservedObject는 SwiftUI 뷰가 외부 객체의 변경 사항을 관찰할 수 있도록 하는 속성 래퍼입니다.
이 객체는 ObservableObject 프로토콜을 채택해야 하며, 내부에서 @Published 속성을 사용하여 변경 사항을 알립니다.
뷰는 @ObservedObject로 선언된 객체의 변경을 자동으로 감지하고, 뷰를 업데이트합니
import SwiftUI
import Combine
class TodoViewModel: ObservableObject {
@Published var todos: [Todo] = []
func addTodo() {
let newTodo = Todo(id: UUID(), title: "New Todo", isCompleted: false)
todos.append(newTodo)
}
}
struct TodoView: View {
@ObservedObject var viewModel: TodoViewModel
var body: some View {
VStack {
List(viewModel.todos) { todo in
Text(todo.title)
}
Button(action: {
viewModel.addTodo()
}) {
Text("Add Todo")
}
}
}
}
@Published
@Published로 선언된 속성은 해당 속성의 값이 변경될 때마다 SwiftUI 뷰에 자동으로 업데이트를 알리게 됩니다.
@Published 속성을 사용하는 클래스는 ObservableObject 프로토콜을 채택해야 합니다.
@Published로 선언된 속성은 자동으로 변경 사항을 게시(publish)하고, 이를 구독하는 뷰나 다른 객체는 이러한 변경 사항을 감지하고 적절하게 반응합니다.