SwiftUI 가계부 앱 개발기 4편 – 카테고리 관리 기능 구현

가계부 앱의 핵심 기능 중 하나는 사용자가 직접 카테고리(예: 식비, 교통비, 급여 등) 를 추가하거나 삭제할 수 있는 기능입니다.
이 글에서는 수입/지출을 구분한 카테고리 관리 UI 구성과 중복 방지 처리, 그리고 UX 흐름까지 상세히 설명합니다.


1. 카테고리 분리 – 수입/지출 탭 구성

사용자는 수입과 지출을 구분하여 카테고리를 관리할 수 있어야 합니다.
이를 위해 SegmentedPicker를 사용하여 탭 전환형 UI를 구성합니다.

swift
Picker("Type Filter", selection: $selectedFilter) {
   Text(NSLocalizedString("income", comment: "수입")).tag("income")
   Text(NSLocalizedString("expense", comment: "지출")).tag("expense")
}
.pickerStyle(.segmented)

선택된 탭에 따라 각각의 카테고리 리스트를 실시간으로 필터링하여 보여줍니다.


2. 카테고리 목록 표시 – CoreData 연동

CoreData의 AppCategory Entity에서 해당하는 유형(income 또는 expense)에 맞는 항목을 필터링하여 리스트에 보여줍니다.

ForEach(categories.filter { $0.type == selectedFilter }) { category in
   Text(category.name ?? "")
}
  • 리스트 상단에는 “카테고리 목록”이라는 텍스트를 헤더로 보여줍니다.
  • 존재하지 않을 경우 “등록된 카테고리가 없습니다” 안내 문구 표시.

3. 카테고리 추가 기능 구현

사용자가 새 카테고리를 입력하고 추가할 수 있도록 TextField와 Button을 배치합니다.

TextField("카테고리 이름 입력", text: $newCategoryName)
   Button("추가") {
   // 공백 체크 및 중복 검사
   // CoreData에 저장
}

중복 방지 처리

같은 이름이 이미 해당 유형에 존재할 경우 경고 메시지를 띄워 추가를 막습니다.

let exists = categories.contains { $0.name == newName && $0.type == selectedFilter }
if exists {
   showDuplicateAlert = true
}

4. 카테고리 삭제 기능

스와이프 제스처로 간편하게 삭제할 수 있도록 .onDelete 기능을 구현합니다.

.onDelete { indexSet in
let toDelete = categories.filter { $0.type == selectedFilter }[index]
   viewContext.delete(toDelete)
}

삭제 후 CoreData 저장을 통해 데이터가 즉시 반영됩니다.


5. UX 구성 – 직관적인 흐름

  • 상단 제목: “카테고리 관리” 텍스트를 Toolbar 최상단에 배치
  • 닫기 버튼은 우측 상단에 “닫기” 버튼으로 제공
  • 추가 필드와 버튼은 깔끔하게 정렬된 HStack으로 구성
  • 리스트 스타일은 .insetGrouped를 사용하여 iOS 설정 화면처럼 통일성 있게 구성

6. 마무리

카테고리 관리 기능은 사용자의 입력 습관과 분류 기준을 앱에 반영할 수 있게 하는 매우 중요한 요소입니다.

SwiftUI의 선언적 UI 구조와 CoreData의 로컬 저장 기능을 결합하여 실시간으로 반영되는 카테고리 관리 기능을 구현했습니다.

SwiftUI 가계부 앱 개발기 5편 – 카드 관리 기능: 결제일 및 청구 주기 설정 에서는 이 카테고리 데이터를 기반으로 한 카드 관리 기능과 결제일 설정 기능을 다뤄보겠습니다.

시리즈 목록