SWIFTUI/Grammar

SwiftUI : #2 MVVM의 간단한 예제

서근 2021. 2. 17. 14:18
반응형

저번 게시글에서 MVVM이 무엇이고 어디에 쓰는지 알아보았습니다.

 

이제 Xcode에서 MVVM을 어떻게 하용하는지 간단한 예제를 통해 알아보려고 합니다.

MVVM의 간단한 예제

새로운 Xcode 프로젝트를 생성하여 시작하도록 하겠습니다. 일반적으로 아래와 같이 생성하게 되면 Model 👉🏻 View 로 직접적으로 화면을 구성해주게 됩니다. 아래 코드를 보면 ageInt로 정해져있습니다. 

//Models
struct Person {
    var name: String
    var age: Int
}

//Views
struct ContentView: View {
    
    let seogun  = Person(name: "서근", age: 26)
    
    var body: some View {
        
        VStack {
            Text(seogun.name)
                .padding()
            Text(String(seogun.age))
        }
    }
}

agebirthday 변수로 바꿔주겠습니다.

//Models
struct Person {
    var name: String
    var birthday: Date
}

//Views
struct ContentView: View {
    
    let seogun  = Person(name: "서근", birthday: Date())
    
    var body: some View {
        
        VStack {
            Text(seogun.name)
                .padding()
        }
    }
}

이제 조금 복잡해집니다. 생년월일을 나이로 변환해야 하고 그것을 넣어줘야 합니다. 그렇기때문에 우리는 ViewModel을 만들어야 합니다. 왜 ViewModel을 만들까요?

 

지금 코드를 보면 Model에서 View로 전달해줄 수 없기 때문이죠!

//ViewMdoel
class ContentViewModel: ObservableObject {
    var seogun  = Person(name: "서근", birthday: Date())
    
    var name: String {
        seogun.name
    }
    var age: String {
        
        //Date를 -> 나이로 변환
        return "27"
    }
    //이름변경 함수 생성
    func changeName(_ name: String) {
        seogun.name = name
    }
}

ViewModel을 생성해줬습니다. 코드를보면 이름, 나이, 이름변경 함수가 있습니다. 이제 이 코드를 View에 전달해줘야합니다.

//Views
struct ContentView: View {
    //ViewModel을 가져온다
    @StateObject var viewModel = ContentViewModel()

    var body: some View {
        
        VStack {
            Text(viewModel.name)
                .padding()
            Text(viewModel.age)
                .padding()
            Button("이름변경") {
                //이름을 "포뇨"로 변경
                viewModel.changeName("포뇨")
            }
        }
    }
}

View안에 ViewModel을 가져오는데 @StateObject로 가져와야 합니다. Text쪽도 위와같이 변경해줬고, Button을 생성해서 클릭시 이름이 '포뇨'로 바뀌게 하려고 합니다. 이렇게 하고 런을 해보면 아무 반응이 없습니다. 왜그럴까요? 

 

ViewModeld@Published속성을 추가해주지 않았기 때문이죠 :)

//ViewMdoel
class ContentViewModel: ObservableObject {
    @Published var seogun  = Person(name: "서근", birthday: Date())

읽어주셔서 감사합니다🤟