본문 바로가기
AI 해보기/딸깍! 일정관리 앱 만들어보기

2. 상세화면 만들기

by yoondoo 2026. 3. 20.
728x90

1. NavigationLink

  • 화면 이동 버튼
  • 카톡에서 채팅방 탭 -> 대화화면
  • 인스타에서 사진 탭 -> 상세 화면

포인트

- NavigationLink는 "탭하면 이 화면으로 가라!"는 명령

- 뒤로가기 버튼은 NavigationStack이 자동으로 만들어줌

2. EventDetailView 만들기

  • SwiftUI에서 새 화면 == 새 struct
  • 새 화면이란?
    • Day1에서 만든 일정 목록 화면
    • 오늘 만들 일정 상세 화면
    • 둘 다 같은 구조지만 다른 내용이다!

3. 화면 사이 데이터 전달

  • 목록에서 선택한 일정을 상세 화면에 넘기는 방법
  • 목록 화면 ->  (같은 내용 가지고 이동) -> 상세 화면
// 목록에서 보내는쪽
NavigationLink {
	EventDetailView(event: event)
    //               ↑ 이 event를 넘긴다.
}

// 상세 화면에서 받는쪽
struct EventDetailView: View {
	let event: Event // 여기서 받는다.
}

4. isAllDay 하루 종일 옵션

  • event에 추가하는 Bool(참/거짓) 필드
    • true : 하루 종일 일정 (크리스마스, 생일 등)
    • false : 특정 시간 일정 (14시 회의)
  • 하루 종일 옵션의 경우 시간을 없애서 깔끔한 view로 보여주자.
struct Event: Identigiable{
	let id = UUID()
    var tatile: String
    var date: Date
    var memo: String
    var isAllDay: Bool   // New!!
}

5. 프롬프트 작성

이전에 만든 일정관리 앱을 이어서 개발할게.

추가할 기능:
1. 일정을 탭하면 상세 화면으로 이동한다
2. 상세 화면에 제목, 날짜, 메모가 표시된다
3. 뒤로가기 버튼으로 목록으로 돌아갈 수 있다
4. Event에 isAllDay(하루 종일) 필드를 추가한다
5. 하루 종일이면 시간 없이 날짜만 표시된다
6. 샘플 데이터 중 2개는 하루 종일로 설정해줘

현재 코드:
[여기에 Day 1의 전체 코드 붙여넣기]

전체 코드를 하나의 파일로 다시 작성해줘.

 

import SwiftUI

// MARK: - Model

struct Event: Identifiable {
    let id = UUID()
    let title: String
    let date: Date
    let memo: String
    let isAllDay: Bool
}

// MARK: - Sample Data

extension Event {
    static let samples: [Event] = {
        let dayFmt = DateFormatter()
        dayFmt.dateFormat = "yyyy-MM-dd"
        
        let timeFmt = DateFormatter()
        timeFmt.dateFormat = "yyyy-MM-dd HH:mm"
        
        return [
            Event(title: "팀 회의",       date: timeFmt.date(from: "2026-03-18 14:00")!, memo: "분기 목표 점검",      isAllDay: false),
            Event(title: "치과 예약",      date: timeFmt.date(from: "2026-03-20 10:30")!, memo: "정기 검진",          isAllDay: false),
            Event(title: "친구 생일 파티",  date: dayFmt.date(from: "2026-03-22")!,        memo: "선물 준비하기",      isAllDay: true),
            Event(title: "프로젝트 마감",   date: timeFmt.date(from: "2026-03-25 18:00")!, memo: "최종 보고서 제출",    isAllDay: false),
            Event(title: "가족 저녁 식사",  date: dayFmt.date(from: "2026-03-30")!,        memo: "레스토랑 예약 완료",  isAllDay: true),
        ]
    }()
}

// MARK: - Helpers

struct DateLabel: View {
    let date: Date
    let isAllDay: Bool
    
    var body: some View {
        if isAllDay {
            Text(date, format: .dateTime.year().month().day())
        } else {
            Text(date, format: .dateTime.year().month().day().hour().minute())
        }
    }
}

// MARK: - Row

struct EventRow: View {
    let event: Event
    
    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text(event.title)
                .font(.headline)
            DateLabel(date: event.date, isAllDay: event.isAllDay)
                .font(.subheadline)
                .foregroundColor(.secondary)
        }
        .padding(.vertical, 4)
    }
}

// MARK: - Detail

struct EventDetailView: View {
    let event: Event
    
    var body: some View {
        List {
            Section("제목") {
                Text(event.title)
                    .font(.title3.bold())
            }
            
            Section("날짜") {
                DateLabel(date: event.date, isAllDay: event.isAllDay)
            }
            
            Section("메모") {
                Text(event.memo)
            }
        }
        .navigationTitle("일정 상세")
        .navigationBarTitleDisplayMode(.inline)
    }
}

// MARK: - List

struct ContentView: View {
    let events = Event.samples
    
    var body: some View {
        NavigationView {
            List(events) { event in
                NavigationLink(destination: EventDetailView(event: event)) {
                    EventRow(event: event)
                }
            }
            .navigationTitle("내 일정")
        }
    }
}

// MARK: - Entry Point

@main
struct MyScheduleApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

6. 확인할 부분

  • 탭으로 이동하고
  • 이동했을 때 event가 원래 가지고 있던 정보를 가지고 있는지

7. 실행 체크

  • [ㅇ] Day 1 코드를 프롬프트에 붙여넣었다
  • [ㅇ] 새 코드를 받아서 실행했다
  • [ㅇ] 일정을 탭해서 상세 화면을 확인했다
  • [ㅇ] 뒤로가기로 목록에 돌아왔다
  • [ㅇ] Day 2 코드를 저장했다
반응형

댓글