[SwiftUI]@State, @ObservedObject

아토시스·2023년 9월 26일
0

SwiftUI

목록 보기
2/2

@State

왜 @State는 오직 Struct에서만 작동을 할까 ?

만약 사용자가 버튼을 누르거나 스크롤을 하거나 텍스트에 상자를 입력했다고 치면, 그 특정 행동은 그 State 즉 상태를 변경한다. 그 이후에 일어날 일은 State가 변경되면 자동으로 변환시켜주는 일을 한다.
사용자 인터페이스를 업데이트하는 것이다.

그렇다면 어떻게 이렇게 할 수 있을까?
View를 사용할 때 ContentView가 실제로 View 프로토콜을 준수한다는 것을 기억해야한다. Body속성을 작성한다. 이것이 View 프로토콜의 유일한 요구 사항이다.

상태를 변경할 때마다 body속성이 재설정 된다. 뷰 자체가 다시 렌더링 되는 것.
따라서 State를 변경 할 때마다 항상 새로운 View에서 렌더링 된다는 점을 기억하자!
그리고 사용자가 그것을 보게 된다.

사용자가 스위치를 켜고 끄는 것처럼 상태를 변경할 때 그 값을 State안에 넣으면 뷰를 렌더링 하게 된다.

이것을 사용하기 위해서는 @State와 Struct를 필수적으로 사용해야 합니다. Strcut 내부의 값이 전체 Struct를 변경할 때마다 전체 구조체가 자동적으로 변경된다.


@ObservedObject / @Published

@State

특정 view에서만 사용하는 프로퍼티

@ObservedObject

복잡한 프로퍼티(여러 프로퍼티나 메서드가 있거나 , 여러 view에서 공유할 수 있는 커스텀 타입이 있는 경우)

  • String이나 integer 같은 간단한 로컬 프로퍼티 대신 외부 참조 타입을 사용한다는 점을 제외하면 @State와 매우 유사하다
  • @ObservedObject와 함꼐 사용하는 타입은 ObservedObject 프로토콜을 따라야한다.
  • @ObservedObject가 데이터가 변경되었음을 view에 알리는 방법은 여러가지가 있지만 가장 쉬운 방법은 @Published 프로퍼티 래퍼를 사용하는 것 - SwiftUI에 view reload를 트리거

class UserSettings: ObservableObject {
   //@ObervedObjet를 사용하기위해 @Published를 할당
   @Published var score = 0
}
 
struct ContentView: View {
   //@state를 지우고 @ObervedObject로 바꿔줌
    @ObservedObject var settings = UserSettings()
 
    var body: some View {
        VStack {
            Text("나의 점수는 \(settings.score)점 입니다.")
            Button(action: {
                self.settings.score += 1
            }) {
                Text("Increase Score")
            }
        }
    }
}

score에 @Published가 붙었기 때문에 이 score가 변경되면 view를 reload하게 된다.


SwiftUI에서 class를 그대로 사용하고 싶을 땐 ?

@ObservedObject property wrapper는 ObservableObject프로토콜에 적합한 유형에만 사용할 수 있으며 실제로 해결하기도 쉽다.

  • FruitViewModel -> protocol : ObservableObject

  • FruitBasicView -> @ObservedObject

결과 화면

profile
오늘보다 더 나은 내일이 되길 바라며

1개의 댓글

comment-user-thumbnail
2023년 10월 6일

아토언니! 좋은 정보 잘 보고 가요~!

답글 달기