적당한 고통은 희열이다

- 댄 브라운 '다빈치 코드' 중에서

Swift iOS 앱 개발/Swift 튜토리얼

[Stanford iOS] Lecture 3. Reactive UI + Protocols + Layout

hongssup_ 2021. 4. 1. 13:48
반응형

Lecture 3. Reactive UI + Protocols + Layout

Reactive Demo - Make Memorize's View always reflect its Model

Varieties of Types

View Layout - How do Views get placed on screen? (demo: adapt CardView's font size to the size of the card)

 

SwiftUI is Reactive!

Reactive Programming :

Model에 변화가 감지되면, 자동으로 View에 나타나도록 해준다.

when changes happen in the Model, automatically show up in the View 

 

[Model] How to modify Model?

struct value 타입이기 때문에 값이 계속 복사된다. 

Model에서 Card를 만들고 ViewModel 넘겨주고 View 넘겨주면 그건 복사본의 복사본. 

Model의 복사본의 값을 변경한다고 해서 원본이 변경되지는 않는다.

그러면 복사하지 말고 원본을 그냥 직접 바로 변경해버리면? 안된다. self는 immutable이다. 그럼 어떡해?

함수를 mutating func으로 선언해서 원본을 바꿀 수 있도록 알려주면 된다!

▶︎ 한마디로 struct 구조체에서 self를 modify하고 싶은 함수들은 모두 mutating func으로 선언해주어야 한다. 

(class와의 차이. class는 언제나 누구나 바꿀 수 있지만, struct에서는 바꿀 수 있도록 알려줘야함.)

초기화 함수 init(initializer) 당연히 changing(setting and creating) self. All inits are mutable.   

 

[ViewModel → View] How to Update UI?

How to implement 'Reactive' Programming 

Model에서의 변화를 감지하여 이를 View에 나타나게 하기 위해서는 ViewModel에 'ObservableObject'라는 프로토콜을 추가해주어야 한다. 이 프로토콜에는 var objectWillChange: ObservableObjectPublisher 가 내장되어 있어, Model 변경될때마다 objectWillChange.send() 를 선언해주면 변경이 되었다는 사실을 View에 알려줄 수 있다. but 코드가 길어지고 intent들이 많아지면 하나하나 다 해주기 힘들 것.  

@Published 라는 property wrapper var model 앞에 넣어주면 Model 변경될때 마다 objectWillChange.send() 자동으로 해준다! 

그런 다음 View에서 이를 받아오기 위해서는 var viewModel 앞에 @ObservedObject 넣어주면 된다. 

그러면 viewModel에서 objectWillChange.send() 호출할 때 마다 알아서 redraw 해준다.

(Swift는 똑똑하니깐 전부 다 새로 redraw 하는 건 아니고 바뀐 부분만 다시 그림. 어짜피 cards는 identifiable이니까!)

▶︎ 정리하면, Model 바뀔 마다 ObservableObject ViewModel에서 @Published wrapper 이를 알아채고 objectWillChange.send()해주면 View에서 @ObservedObject 이를 감지하고 redraw 해준다. => 이것이 바로 Reactive Programming   

 

 

  

 

 

 

728x90
반응형