[SwiftUI] 데이터 바인딩의 세가지 방법(2)

Hashswim·2024년 3월 8일
0

2. Obserable 객체 프로퍼티

상태 프로퍼티는 하위뷰가 아니거나
State 바인딩이 구현되어 있지 않은 다른 뷰에서는 사용이 접근할 수 없다..

또 부모 뷰에 선언되어 있기 때문에 부모 뷰가 사라지면 프로퍼티 또한 사라져 버린다

여러 다른 뷰들이 외부에서 접근 가능한 지속적인 데이터를 표현하기 위해서는 Observable객체를 사용할 수 있다.

어떻게 사용하나..?

  • 게시
import Foundation
//combine 프레임워크 삽입
import Combine

class MyData: ObservedObject {
	//@Published 프로퍼티 래퍼를 통해 래퍼 프로퍼티 값이 변경 될때 마다 구독자에게 업데이트를 알림
	@Published var userCount = 0
    @Published var currentUser = ""
    
    init() {
    	//데이터 초기화
        updateData()
    }
    
    func updateData() {
    	//데이터 새로고침
    }
}
  • 구독
import SwiftUI

struct ContevtView: View {
	//@ObservedObject: 객체의 참조를 뷰가 소유하지 않음
    //@StateObject: 객체의 참조를 뷰가 소유
    @StateObject var myData: MyData = MyData()
    //@ObservedObject var myData: MyData = MyData()
    
    var body: some View {
    	Text("\(myData.currentUser) - \(myData.userCount)")
    }
}

struct ContentView_Previews: PreviewProvider {
	static var previews: some View {
    	ContentView(myData: MyData())
    }
}

@StateObject를 사용하면 참조를 선언한 뷰가 참조를 소유하게 되므로 해당 데이터를 계속 필요로 하는 동안에는 사라지지 않는다!(특별한 이유가 없다면 @StateObject를 사용)

3. Environment 객체

구독되는 객체는 특정 상태가 앱 내의 몇몇 뷰에서 사용될 때 적합하다.
그런데 다른 뷰로 이동을 하면서 이동되는 뷰에서도 똑같은 구독 객체에 접근해야 한다면 어떻게 할까?

NavigatoinLink(destination: SecondeView(myData)) {}
위와 같이 해당 객체에 대한 참조를 전달하면 된다.

다만, 앱내의 여러 뷰가 동일한 구독 객체에 접근해야 한다면 전달이 복잡해진다..

이때 Enviroment객체를 사용하는 것이 합리적일 수 있다.

  • 게시
	import Foundation
    import Combine

	//Observable 객체와 같이 선언
	class SpeedSetting: ObservedObject {
    	@Published var speed: 0.0
    }
  • 구독
	import SwiftUI

	struct SpeedControlView: View {
    	//@EnvironmentObject 프로퍼티 래퍼 사용
    	@EnvironmentObject var speedsetting: SpeedSetting
        
        var body: some View {
        	Slider(value: $speedSetting.speed, in: 0...100)
        }
    }
	import SwiftUI

	struct ContentView: View {
    	let speedSetting = SpeedSetting()
        
        var body: some View {
        	SpeedControlView()
        }.environmentObject(speedSetting)
        //speedSetting 인스턴스를 계층 구조 전부에 주입
    }

이렇게 하면 Observable객체와 같이 작동하지만 뷰 이동시에 계층 구조를 따라 전달되지 않고
ContentView의 모든 하위 뷰에서 동일한 객체에 접근할 수 있다.

공식 문서 예제를 살펴보다 보니 Combine 프레임워크 관련 내용이 많아 이해가 어려웠다..ㅠ

추후 Combine을 제대로 한번 다뤄야겠다.

0개의 댓글