[TIL] 화면 분석 후 ViewModel 만들기

Eden·2025년 1월 10일
2

TIL

목록 보기
93/132
post-thumbnail

재사용 할 모달의 뷰 모델을 구현하기 위해 화면의 요구사항과 동작을 파악한 후, 뷰 모델의 책임을 정의해야한다.

1. 화면 분석

공통 요소

  • 제목: 화면 상단에 단어장 수정하기 또는 새로운 단어장 만들기 표시
  • 단어장 이름 입력: 단어장 이름을 입력하는 텍스트 필드.
  • 언어 선택 버튼들: 한국어, 영어, 중국어 등 언어 버튼들이 표시되며, 선택된 버튼은 활성화 스타일로 표시
  • 확인 버튼: 추가하기 또는 수정하기 버튼으로, 모드에 따라 텍스트가 다름

동작 요소

  1. 모드에 따라 UI 변경
    • 단어장 수정하기와 새로운 단어장 만들기 모드에 따라 버튼 텍스트, 초기 텍스트 필드 값이 다름.
    • 수정 모드에서는 초기값(단어장 이름과 언어)이 제공됨.
  2. 단어장 이름 입력
    • 입력 필드에서 사용자가 텍스트를 입력
  3. 언어 선택
    • 언어 버튼을 클릭하면 해당 언어가 선택되고, 스타일 업데이트
  4. 확인 버튼 동작
    • 추가하기 혹은 수정하기 버튼을 누르면 데이터를 저장하거나 업데이트

2. 뷰 모델의 책임 정의

뷰 모델을 상태 관리와 로직 처리를 담당해야 한다.

상태

  1. 모드: create / edit
  2. 단어장 이름: 텍스트 필드의 값.
  3. 선택된 언어: 현재 선택된 언어
  4. 언어 목록: 선택 가능한 언어 목록.

로직

  1. 모드 설정
    초기화 시 모드를 설정하고, 초기 데이터를 반영
  2. 단어장 이름 변경
    사용자가 텍스트 필드에 값을 입력할 때 상태를 업데이트
  3. 언어 선택 로직
    언어 버튼 클릭시 선택된 언어를 업데이트하고 UI 반영
  4. 확인 버튼 동작
    입력된 데이터를 저장하거나 업데이트 하는 로직 처리

3. 뷰 모델 기획

상태와 동작 정의

import Foundation

// MARK: - VocaBookModalMode Enum
enum VocaBookModalMode {
    case create
    case edit(title: String, language: Language)
}

// MARK: - Language Enum
enum Language: Int {
    case korean = 0
    case english
    case chinese
    case japanese
    case german
    
    var koreanTitle: String {
        switch self {
        case .korean: return "한국어"
        case .english: return "영어"
        case .chinese: return "중국어"
        case .japanese: return "일본어"
        case .german: return "독일어"
        }
    }
}

// MARK: - VocaBookModalViewModel Class
class VocaBookModalViewModel {
    // MARK: - Properties
    
    // 현재 모드
    private(set) var mode: VocaBookModalMode
    
    // 단어장 이름
    var bookName: String = "" {
        didSet {
            bookNameChanged?(bookName)
        }
    }
    
    // 선택된 언어
    var selectedLanguage: Language = .english {
        didSet {
            languageSelectionChanged?(selectedLanguage)
        }
    }
    
    // 언어 목록
    let availableLanguages: [Language] = [.korean, .english, .chinese, .japanese, .german]
    
    // 상태 변화 콜백
    var bookNameChanged: ((String) -> Void)?
    var languageSelectionChanged: ((Language) -> Void)?
    var dismissModal: (() -> Void)?
    
    // MARK: - Initialization
    
    init(mode: VocaBookModalMode) {
        self.mode = mode
        switch mode {
        case .create:
            bookName = ""
            selectedLanguage = .english
        case .edit(let title, let language):
            bookName = title
            selectedLanguage = language
        }
    }
    
    // MARK: - Methods
    
    // 단어장 이름 변경
    func updateBookName(_ name: String) {
        bookName = name
    }
    
    // 언어 선택
    func selectLanguage(_ language: Language) {
        selectedLanguage = language
    }
    
    // 확인 버튼 동작
    func confirm() {
        if mode == .create {
            // 단어장 추가 로직
            print("단어장 추가: \(bookName), \(selectedLanguage.koreanTitle)")
        } else if case .edit(let title, _) = mode {
            // 단어장 수정 로직
            print("단어장 '\(title)' 수정: \(bookName), \(selectedLanguage.koreanTitle)")
        }
        dismissModal?()
    }
}
profile
Frontend 🌐 and iOS  🫶🏻

1개의 댓글

comment-user-thumbnail
2025년 1월 11일

오옹 UI 깔끔해서 이쁘다,, 그리고 5개국어라니.. ㄷㄷ 기대되네요!

답글 달기

관련 채용 정보