SwiftUI Lecture 3 : Reactive UI, Protocols, Layout

budlebee·2020년 8월 15일
0

Stanford CS193p

목록 보기
3/4

본 시리즈는 Stanford cs193p 강의(https://cs193p.sites.stanford.edu)를 듣고 필요한 내용을 정리한 것입니다.


카드를 선택했을때 뒤집히는 함수를 만들어보자. 모델에서 choose 함수를 다음과 같이 수정하면 에러가 뜬다.

  1. 함수의 argument 는 기본적으로 let이고
  2. 구조체는 값이 어디론가 넘겨질때마다 원본의 복사본이 만들어져 전달된다(레퍼런스 타입인 클래스와의 차이점). 복사본을 바꿔봐야 원본은 바뀌지 않는다.

구조체 내부의 함수가 구조체 내부의 프로퍼티를 바꾸기 위해선 mutating 키워드가 필요하다.

mutating func choose(card: Card) {
        print("card chosen: \(card)")
        let chosenIndex: Int = self.index(of: card)
        self.cards[chosenIndex].isFaceUp = !self.cards[chosenIndex].isFaceUp
    }
    
// self.cards 카드의 id와, 선택한 card 의 id 가 같으면 해당 위치 index 를 리턴.
// 하나도 맞는게 없다면, 임시로 0을 리턴.
func index(of card: Card) -> Int {
    for index in 0..<self.cards.count {
        if self.cards[index].id == card.id {
            return index
        }
    }
    return 0 // TODO: bogus!
}

하지만 choose 함수를 수정해도, 카드를 클릭했을때 변화가 없다. 모델의 변화에 뷰가 반응하게끔(reactvie) 하려면 뷰모델에서 ObservableObject 을 사용해야 한다.
그리고 오브젝트가 변화될것임을 퍼블리싱 하는 프로퍼티 래퍼 @Published 를 추가한다.

class EmojiMemoryGame : ObservableObject {
	@Published private var model: MemoryGame<String> = EmojiMemoryGame.createMemoryGame() 
    ...
}

또는 choose 함수 안에, objectWillChange.send() 라는 메소드를 호출해서 choose 함수 실행때마다 오브젝트 변화를 퍼블리싱 해도 된다. 하지만 웬만한 경우 @Published 프로퍼티 래퍼를 사용하게 된다.

뷰모델에서 변화를 퍼블리싱 했으니, 뷰에서 구독하게 하자. @ObservedObject 프로퍼티 래퍼를 뷰 구조체에 추가한다.

@ObservedObject var viewModel: EmojiMemoryGame

카드를 클릭할때마다 카드가 뒤집히는 걸 관찰할 수 있다.

0개의 댓글