애플 디벨로퍼 아카데미/하루의 날씨

[하루의 날씨] ViewController를 재사용해보자

여성일 2025. 9. 23. 20:19
728x90
문제 상황?

 날씨(메모) 작성과 편집 View가 완전히 동일한 UI를 사용한다. 같은 화면 구성을 또 다른 파일로 만들어 쓰는 것은 유지보수나 개발 공수 측면에서 불필요하다고 판단했다. 그래서 기존에 사용하던 작성 뷰(WriteViewController)를 그대로 재사용하는 방식으로 접근해보기로 했다. 

 

enum을 써봅시다요

 핵심은 하나의 ViewController를 작성/편집 2가지 모드로 동작하게 만드는 것이다. 이를 위해 아래와 같이 구조를 변경했다.

 

1. ViewMode Enum 정의 

enum ViewMode {
  case editMode(existing: TodayWeather)
  case writeMode
}

 

2. WriteViewController 초기화 시 ViewMode를 주입

final class WriteViewController: UIViewController {
  private let mode: WriteMode

  init(mode: WriteMode) {
      self.mode = mode
      super.init(nibName: nil, bundle: nil)
  }

  required init?(coder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
  }
}

 

3. 모드별 초기 UI 세팅

override func viewDidLoad() {
  super.viewDidLoad()
  applyModeInitialSetup()
}

func applyModeInitialSetup() {
    switch mode {
    case .writeMode:
      let today = Date()
      viewModel.selectDate = today
      
      var config = dateLabelButton.configuration
      config?.title = today.toKoreanString()
      dateLabelButton.configuration = config
      
      toolbar.setAlignmentButton(viewModel.alignment)
      
    case .editMode(let existing):
      toolbar.setAlignmentButton(existing.alignment)
      viewModel.selectDate = existing.date
      var config = dateLabelButton.configuration
      config?.title = existing.date.toKoreanString()
      dateLabelButton.configuration = config
      
      writeView.text = existing.content
      viewModel.inputText = existing.content
      
      writeView.setTextAlignment(existing.alignment)
      viewModel.alignment = existing.alignment
      
      let weatherImage = UIImage(named: existing.weather) ?? .happy
      weatherButton.setImage(weatherImage, for: .normal)
      viewModel.selectedWeather = Weather(rawValue: existing.weather) ?? .happy
      
      if let data = existing.imageData, let img = UIImage(data: data) {
        writeView.configure(image: img)
        viewModel.imageData = data
      } else {
        writeView.configure(image: nil)
        viewModel.imageData = nil
      }
    }
  }

 

4. 저장 버튼 동작 분기

toolbar.onSaveButtonTapped = { [weak self] in
      guard let self = self else { return }
      self.writeView.endEditingIfNeeded()
      
      switch self.mode {
      case .writeMode:
        self.viewModel.save()
      case .editMode(let existing):
        self.viewModel.update(existing: existing)
  }
}

 

 결과적으로, 작성 화면과 편집 화면을 하나의 WriteViewController로 통합하면서 유지보수성과 생산성을 동시에 높일 수 있었다.

중복된 코드를 없애고, 모드 분기만 잘 설계하면 작성과 편집을 모두 지원할 수 있었다는 점에서 큰 이점이 있었다.