From 2cfbdcb76ae73e0a851e35007e27991e9ae0a284 Mon Sep 17 00:00:00 2001 From: Hyemin Heo Date: Thu, 16 May 2024 22:08:58 +0900 Subject: [PATCH] =?UTF-8?q?#26=20[Chore]=20=ED=8F=B4=EB=8D=94=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Score/Score/View/Calendar/CalendarView.swift | 136 ------------------ .../Calendar/CalendarGridItem.swift | 30 +++- .../View/MyPage/Calendar/CalendarView.swift | 132 +++++++++++++++++ 3 files changed, 155 insertions(+), 143 deletions(-) delete mode 100644 Score/Score/View/Calendar/CalendarView.swift rename Score/Score/View/{ => MyPage}/Calendar/CalendarGridItem.swift (70%) create mode 100644 Score/Score/View/MyPage/Calendar/CalendarView.swift diff --git a/Score/Score/View/Calendar/CalendarView.swift b/Score/Score/View/Calendar/CalendarView.swift deleted file mode 100644 index b571813..0000000 --- a/Score/Score/View/Calendar/CalendarView.swift +++ /dev/null @@ -1,136 +0,0 @@ -// -// CalendarView.swift -// Score -// -// Created by sole on 4/12/24. -// - -import ComposableArchitecture -import SwiftUI - -//MARK: - CalendarView - -struct CalendarView: View { - let store: StoreOf - - var body: some View { - WithViewStore(store, - observe: { $0 }) { viewStore in - VStack(spacing: 9) { - // Calendar Header Section - // year, month, buttons to control appearedMonth - calendarHeader(viewStore: viewStore) - - // WeekOfDay Label Section - dayOfWeekLabel(viewStore: viewStore) - - // Calendar Section - calendarGrid(viewStore: viewStore) - } - .layout() - .onAppear { - viewStore.send(.viewAppearing) - } - } - } - - //MARK: - calendarHeader - - @ViewBuilder - func calendarHeader(viewStore: - ViewStore - ) -> some View { - HStack { - Group { - Text(String( - format: "%4d", - viewStore.appearedYear)) - - Text((Month(rawValue: viewStore.appearedMonth) ?? - .october).capitalizedString()) - } - .pretendard(weight: .black, - size: .m) - - Spacer() - - /// FIXME: Asset으로 변경 - Button { - viewStore.send(.decrementMonthButtonTapped) - } label: { - Image(systemName: "chevron.left") - .foregroundStyle(Color.brandColor( - color: .sub1) - ) - .frame(width: 34, - height: 34) - } - - Button { - viewStore.send(.incrementMonthButtonTapped) - } label: { - Image(systemName: "chevron.right") - .foregroundStyle(Color.brandColor( - color: .sub1) - ) - .frame(width: 34, - height: 34) - } - } - } - - //MARK: - dayOfWeekLabel - - @ViewBuilder - func dayOfWeekLabel(viewStore: - ViewStore - ) -> some View { - HStack(spacing: 0) { - ForEach(DayOfWeek.allCases, id: \.self) { dayOfWeek in - Text(dayOfWeek.stringValue()) - .pretendard(.body3) - } - .layoutOfCalendarItem() - } - } - - //MARK: - calendarGrid - - @ViewBuilder - func calendarGrid( - viewStore: ViewStore - ) -> some View { - VStack(spacing: 0) { - ForEach(viewStore.appearedDateComponentsMatrix, - id: \.self) { dateComponentsArray in - HStack(spacing: 0) { - ForEach(dateComponentsArray, - id: \.self) { dateComponentsWithID in - CalendarGridItem(store: viewStore, - dateComponents: dateComponentsWithID.dateComponents) { - viewStore.send(.dayComponentButtonTapped(dateComponentsWithID.dateComponents)) - } - } - } - } - } - } - -} - -//MARK: - Preview - -#Preview { - CalendarView(store: .init(initialState: CalendarFeature.State( - appearedYear: 0, - appearedMonth: 0, - appearedDay: 0, - appearedDateComponentsMatrix: [], - selectedDateComponents: nil), - reducer: { - CalendarFeature().body - })) -} diff --git a/Score/Score/View/Calendar/CalendarGridItem.swift b/Score/Score/View/MyPage/Calendar/CalendarGridItem.swift similarity index 70% rename from Score/Score/View/Calendar/CalendarGridItem.swift rename to Score/Score/View/MyPage/Calendar/CalendarGridItem.swift index a19fcb1..6feed50 100644 --- a/Score/Score/View/Calendar/CalendarGridItem.swift +++ b/Score/Score/View/MyPage/Calendar/CalendarGridItem.swift @@ -10,17 +10,19 @@ import SwiftUI //MARK: - CalendarGridItem -// - FIXME: CalendarView에서 무조건 store를 받아와야 하는데, 효율적인지? /// - Parameters: /// - store: ViewStore CalendarView에서 받아옵니다. /// - dateComponents: DateComponents를 정의합니다. /// - action: 사용자가 컴포넌트를 Tap했을 때 수행할 동작을 정의합니다. struct CalendarGridItem: View { - let store: ViewStore + let store: StoreOf + @ObservedObject var viewStore: ViewStoreOf + let dateComponents: DateComponents? let action: () -> (Void) + //MARK: - style + private var style: SCNumberIconStyle { guard let dateComponents else { @@ -35,7 +37,7 @@ struct CalendarGridItem: View { } // - FIXME: 오늘 날짜가 black인지? 디자인 확인 필요 - if store.state.selectedDateComponents == dateComponents { + if viewStore.state.selectedDateComponents == dateComponents { return .gray } @@ -44,11 +46,24 @@ struct CalendarGridItem: View { return .plain } + //MARK: - init + + init(store: StoreOf, + dateComponents: DateComponents? = nil, + action: @escaping () -> Void) { + self.store = store + self.dateComponents = dateComponents + self.action = action + self.viewStore = ViewStore(store, + observe: { $0 }) + } + + //MARK: - body + var body: some View { Button(action: action) { SCNumberIcon(style: style, - number: dateComponents?.day - ?? 0) + number: dateComponents?.day ?? 0) /// 양쪽 layout padding 효과 .layoutOfCalendarItem() .background { @@ -71,7 +86,8 @@ struct CalendarGridItem: View { //MARK: - Preview #Preview { - CalendarGridItem(store: .init(.init(initialState: CalendarFeature.State(appearedYear: 0, appearedMonth: 0, appearedDay: 0, appearedDateComponentsMatrix: []), reducer: {CalendarFeature().body}), observe: {$0}), dateComponents: nil) { + CalendarGridItem(store: .init(initialState: .init(), + reducer: { CalendarFeature() })) { } } diff --git a/Score/Score/View/MyPage/Calendar/CalendarView.swift b/Score/Score/View/MyPage/Calendar/CalendarView.swift new file mode 100644 index 0000000..7718773 --- /dev/null +++ b/Score/Score/View/MyPage/Calendar/CalendarView.swift @@ -0,0 +1,132 @@ +// +// CalendarView.swift +// Score +// +// Created by sole on 4/12/24. +// + +import ComposableArchitecture +import SwiftUI + +//MARK: - CalendarView + +struct CalendarView: View { + let store: StoreOf + @ObservedObject var viewStore: ViewStoreOf + + init(store: StoreOf) { + self.store = store + self.viewStore = ViewStore(store, + observe: { $0 }) + } + + var body: some View { + VStack(spacing: 9) { + // Calendar Header Section + // year, month, buttons to control appearedMonth + calendarHeader() + + // WeekOfDay Label Section + dayOfWeekLabel() + + // Calendar Section + /// frame: calendarGrid의 높이에 따라 View가 움직이는 현상을 방지합니다. + calendarGrid() + .frame(height: .calendarItemSize * 6) + } + .layout() + .onAppear { + store.send(.viewAppearing) + } + } + + //MARK: - calendarHeader + + @ViewBuilder + func calendarHeader() -> some View { + HStack { + Group { + Text(String( + format: "%4d", + viewStore.appearedYear)) + + Text((Month(rawValue: viewStore.appearedMonth) ?? + .october).capitalizedString()) + } + .pretendard(weight: .black, + size: .m) + + Spacer() + + /// FIXME: Asset으로 변경 + Button { + store.send(.decrementMonthButtonTapped) + } label: { + Image(systemName: "chevron.left") + .foregroundStyle( + Color.brandColor( + color: .sub1 + ) + ) + .frame(width: 34, + height: 34) + } + + Button { + store.send(.incrementMonthButtonTapped) + } label: { + Image(systemName: "chevron.right") + .foregroundStyle( + Color.brandColor( + color: .sub1 + ) + ) + .frame(width: 34, + height: 34) + } + } + } + + //MARK: - dayOfWeekLabel + + @ViewBuilder + func dayOfWeekLabel() -> some View { + HStack(spacing: 0) { + ForEach(DayOfWeek.allCases, + id: \.self) { dayOfWeek in + Text(dayOfWeek.stringValue()) + .pretendard(.body3) + } + .layoutOfCalendarItem() + } + } + + //MARK: - calendarGrid + + @ViewBuilder + func calendarGrid() -> some View { + VStack(spacing: 0) { + ForEach(viewStore.appearedDateComponentsMatrix, + id: \.self) { dateComponentsArray in + HStack(spacing: 0) { + ForEach(dateComponentsArray, + id: \.self) { dateComponentsWithID in + CalendarGridItem( + store: store, + dateComponents: dateComponentsWithID.dateComponents + ) { + store.send(.dayComponentButtonTapped(dateComponentsWithID.dateComponents)) + } + } + } + } + } + } +} + +//MARK: - Preview + +#Preview { + CalendarView(store: .init(initialState: .init(), + reducer: { CalendarFeature() })) +}