Skip to content

Commit 89b67b7

Browse files
authored
Merge pull request #173 from TEAM-Cherrish/fix/#172-로딩뷰
Refactor/#172 로딩뷰 추가
2 parents c9abd43 + 3a585ca commit 89b67b7

14 files changed

Lines changed: 280 additions & 159 deletions

File tree

Cherrish-iOS/Cherrish-iOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/CalendarMain/CalendarView.swift

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,56 @@ struct CalendarView: View {
2525
@EnvironmentObject private var calendarCoordinator: CalendarCoordinator
2626
@StateObject var viewModel: CalendarViewModel
2727
@StateObject var homeCalendarFlowState: HomeCalendarFlowState
28+
@State var calendarMode: CalendarMode = .none
29+
@State var selectedProcedureID: Int? = nil
30+
31+
var body: some View {
32+
ZStack {
33+
if viewModel.isLoading {
34+
CherrishLoadingView()
35+
} else {
36+
CalendarContentView(
37+
viewModel: viewModel,
38+
homeCalendarFlowState: homeCalendarFlowState,
39+
calendarMode: $calendarMode,
40+
selectedProcedureID: $selectedProcedureID
41+
)
42+
}
43+
}
44+
.task (id: viewModel.currentMonth){
45+
if calendarMode == .none {
46+
do {
47+
try await viewModel.fetchProcedureCountsOfMonth()
48+
try await viewModel.fetchTodayProcedureList()
49+
} catch {
50+
CherrishLogger.error(error)
51+
}
52+
}
53+
}
54+
.onChange(of: homeCalendarFlowState.treatmentDate) { _, date in
55+
if let date = date {
56+
viewModel.updateDate(date: date)
57+
homeCalendarFlowState.treatmentDate = nil
58+
}
59+
}
60+
.onAppear {
61+
if let date = homeCalendarFlowState.treatmentDate {
62+
viewModel.updateDate(date: date)
63+
homeCalendarFlowState.treatmentDate = nil
64+
}
65+
}
66+
}
67+
}
68+
69+
private struct CalendarContentView: View {
70+
@EnvironmentObject private var calendarCoordinator: CalendarCoordinator
71+
@ObservedObject var viewModel: CalendarViewModel
72+
@ObservedObject var homeCalendarFlowState: HomeCalendarFlowState
2873
@State private var topGlobalY: CGFloat = .zero
2974
@State private var initialTopGlobalY: CGFloat? = nil
3075
@State private var bottomOffsetY: CGFloat = .zero
31-
@State private var calendarMode: CalendarMode = .none
32-
@State private var selectedProcedureID: Int? = nil
76+
@Binding var calendarMode: CalendarMode
77+
@Binding var selectedProcedureID: Int?
3378
@State private var buttonState: ButtonState = .active
3479

3580
private let scrollAreaHeight: CGFloat = 184.adjustedH
@@ -40,6 +85,7 @@ struct CalendarView: View {
4085
let weekdays: [String] = ["", "", "", "", "", "", ""]
4186
let columns = Array(repeating: GridItem(.fixed(40.adjustedW), spacing: 8), count: 7)
4287

88+
4389
var body: some View {
4490
VStack {
4591
Spacer()
@@ -56,33 +102,10 @@ struct CalendarView: View {
56102
}
57103
Spacer()
58104
}
59-
.task (id: viewModel.currentMonth){
60-
if calendarMode == .none {
61-
do {
62-
try await viewModel.fetchProcedureCountsOfMonth()
63-
try await viewModel.fetchTodayProcedureList()
64-
} catch {
65-
CherrishLogger.error(error)
66-
}
67-
}
68-
}
69-
.onChange(of: homeCalendarFlowState.treatmentDate) { _, date in
70-
if let date = date {
71-
viewModel.updateDate(date: date)
72-
homeCalendarFlowState.treatmentDate = nil
73-
}
74-
}
75-
.onAppear {
76-
if let date = homeCalendarFlowState.treatmentDate {
77-
viewModel.updateDate(date: date)
78-
homeCalendarFlowState.treatmentDate = nil
79-
}
80-
}
81105
.background(.gray0)
82106
}
83107
}
84-
85-
extension CalendarView {
108+
extension CalendarContentView {
86109
private var calendarHeader: some View {
87110
VStack {
88111
HStack {
@@ -330,7 +353,7 @@ extension CalendarView {
330353

331354
}
332355

333-
extension CalendarView {
356+
extension CalendarContentView {
334357
private var scrollViewTopMarkerView: some View {
335358
GeometryReader { proxy in
336359
Color.clear

Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/CalendarMain/CalendarViewModel.swift

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ final class CalendarViewModel: ObservableObject {
2222
@Published private(set) var treatmentDate: String = ""
2323
@Published private(set) var downtimeByDay: [String : DowntimeDayState] = [:]
2424
@Published private(set) var selectedDowntime: ProcedureDowntimeEntity?
25+
@Published private(set) var isLoading: Bool = true
2526

2627
private let fetchProcedureCountOfMonthUseCase: FetchProcedureCountOfMonth
2728
private let fetchTodayProcedureListUseCase: FetchTodayProcedureListUseCase
@@ -103,26 +104,46 @@ final class CalendarViewModel: ObservableObject {
103104

104105
@MainActor
105106
func fetchProcedureCountsOfMonth() async throws {
107+
isLoading = true
106108
let calendar = Calendar.current
107109
let targetDate = getCurrentMonth(addingMonth: currentMonth)
108110
let year = calendar.component(.year, from: targetDate)
109111
let month = calendar.component(.month, from: targetDate)
110112

111-
let response = try await fetchProcedureCountOfMonthUseCase.execute(year: year, month: month)
112-
procedureCountOfMonth = response.dailyProcedureCounts
113+
do {
114+
let response = try await fetchProcedureCountOfMonthUseCase.execute(year: year, month: month)
115+
isLoading = false
116+
procedureCountOfMonth = response.dailyProcedureCounts
117+
} catch {
118+
CherrishLogger.error(error)
119+
}
113120
}
114121

115122
@MainActor
116123
func fetchTodayProcedureList() async throws {
124+
isLoading = true
117125
treatmentDate = selectedDate.toDateString()
118-
procedureList = try await fetchTodayProcedureListUseCase.execute(date: treatmentDate)
126+
127+
do {
128+
procedureList = try await fetchTodayProcedureListUseCase.execute(date: treatmentDate)
129+
isLoading = false
130+
} catch {
131+
CherrishLogger.error(error)
132+
}
119133
}
120134

121135
@MainActor
122136
func fetchDowntimeByDay(procedureId: Int) async throws {
123-
let downtimeList = try await fetchProcedureDowntimeUseCase.execute(id: procedureId)
124-
selectedDowntime = downtimeList
125-
mapToDowntimeDays(procedure: downtimeList)
137+
isLoading = true
138+
139+
do {
140+
let downtimeList = try await fetchProcedureDowntimeUseCase.execute(id: procedureId)
141+
isLoading = false
142+
selectedDowntime = downtimeList
143+
mapToDowntimeDays(procedure: downtimeList)
144+
} catch {
145+
CherrishLogger.error(error)
146+
}
126147
}
127148

128149
func updateDate(date: Date) {

Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/NoTreatment/NoTreatmentFilterView.swift

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,36 @@ struct NoTreatmentFilterView: View {
2525
var body: some View {
2626
VStack(spacing: 0) {
2727
TitleHeaderView(title: viewModel.selectedCategory?.title ?? "")
28-
29-
ScrollView(.vertical, showsIndicators: false){
30-
Spacer()
31-
.frame(height: 18.adjustedH)
32-
33-
ForEach(viewModel.treatments, id: \.id) { treatment in
34-
TreatmentRowView(
35-
displayMode: .checkBoxView,
36-
treatmentEntity: treatment,
37-
isSelected: .constant(viewModel.isSelected(treatment)),
38-
action: {
39-
if viewModel.isSelected(treatment) {
40-
viewModel.removeTreatment(treatment)
41-
} else {
42-
viewModel.addTreatment(treatment)
43-
44-
}
45-
}
46-
)
47-
.padding(.horizontal, 25.adjustedW)
28+
if viewModel.isLoading {
29+
CherrishLoadingView()
30+
} else {
31+
ScrollView(.vertical, showsIndicators: false) {
32+
Spacer()
33+
.frame(height: 18.adjustedH)
4834

35+
ForEach(viewModel.treatments, id: \.id) { treatment in
36+
TreatmentRowView(
37+
displayMode: .checkBoxView,
38+
treatmentEntity: treatment,
39+
isSelected: .constant(viewModel.isSelected(treatment)),
40+
action: {
41+
if viewModel.isSelected(treatment) {
42+
viewModel.removeTreatment(treatment)
43+
} else {
44+
viewModel.addTreatment(treatment)
45+
46+
}
47+
}
48+
)
49+
.padding(.horizontal, 25.adjustedW)
50+
51+
}
52+
Spacer()
53+
.frame(height: 198.adjustedH)
4954
}
50-
Spacer()
51-
.frame(
52-
height: viewModel.selectedTreatments.isEmpty ?
53-
24.adjustedH : scrollViewHeight.adjustedH + 24.adjustedH
54-
)
5555
}
5656

57+
5758
}
5859
.task {
5960
await viewModel.fetchNoTreatments()

Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/View/NoTreatment/NoTreatmentView.swift

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -151,63 +151,67 @@ private struct TreatmentSelectedCategory: View {
151151
]
152152

153153
var body: some View {
154-
VStack(spacing: 0) {
155-
Spacer()
156-
.frame(height: 50.adjustedH)
157-
158-
HStack(spacing: 0) {
159-
VStack(alignment: .leading, spacing: 0) {
160-
TypographyText(
161-
"요즘 가장 신경 쓰이는 ",
162-
style: .title1_sb_18,
163-
color: .gray1000
164-
)
165-
.frame(height: 27.adjustedH)
154+
if viewModel.isLoading {
155+
CherrishLoadingView()
156+
} else {
157+
VStack(spacing: 0) {
158+
Spacer()
159+
.frame(height: 50.adjustedH)
160+
161+
HStack(spacing: 0) {
162+
VStack(alignment: .leading, spacing: 0) {
163+
TypographyText(
164+
"요즘 가장 신경 쓰이는 ",
165+
style: .title1_sb_18,
166+
color: .gray1000
167+
)
168+
.frame(height: 27.adjustedH)
169+
170+
TypographyText(
171+
"외모 고민은 무엇인가요?",
172+
style: .title1_sb_18,
173+
color: .gray1000
174+
)
175+
.frame(height: 27.adjustedH)
176+
Spacer()
177+
.frame(height: 4.adjustedH)
178+
TypographyText(
179+
"선택한 고민을 기준으로 시술 정보를 정리해줘요.",
180+
style: .body1_m_14,
181+
color: .gray700
182+
)
183+
.frame(height: 20.adjustedH)
184+
185+
}
186+
.frame(height: 78.adjustedH)
166187

167-
TypographyText(
168-
"외모 고민은 무엇인가요?",
169-
style: .title1_sb_18,
170-
color: .gray1000
171-
)
172-
.frame(height: 27.adjustedH)
173188
Spacer()
174-
.frame(height: 4.adjustedH)
175-
TypographyText(
176-
"선택한 고민을 기준으로 시술 정보를 정리해줘요.",
177-
style: .body1_m_14,
178-
color: .gray700
179-
)
180-
.frame(height: 20.adjustedH)
181-
182189
}
183-
.frame(height: 78.adjustedH)
190+
.padding(.horizontal, 34.adjustedW)
184191

185-
Spacer()
186-
}
187-
.padding(.horizontal, 34.adjustedW)
188-
189-
ScrollView(.vertical, showsIndicators:false) {
190-
Spacer()
191-
.frame(height: 40.adjustedH)
192-
LazyVGrid(columns: columns, spacing: 12.adjustedH) {
193-
ForEach(viewModel.categories, id: \.id) { category in
194-
SelectionChip(
195-
title: category.title,
196-
isSelected: Binding(
197-
get: {
198-
viewModel.selectedCategory == category
199-
},
200-
set: {
201-
isSelected in
202-
guard isSelected else {
203-
return
192+
ScrollView(.vertical, showsIndicators:false) {
193+
Spacer()
194+
.frame(height: 40.adjustedH)
195+
LazyVGrid(columns: columns, spacing: 12.adjustedH) {
196+
ForEach(viewModel.categories, id: \.id) { category in
197+
SelectionChip(
198+
title: category.title,
199+
isSelected: Binding(
200+
get: {
201+
viewModel.selectedCategory == category
202+
},
203+
set: {
204+
isSelected in
205+
guard isSelected else {
206+
return
207+
}
208+
viewModel.selectCategory(category)
204209
}
205-
viewModel.selectCategory(category)
206-
}
210+
)
207211
)
208-
)
209-
}
210-
} .padding(.horizontal, 34.adjustedW)
212+
}
213+
} .padding(.horizontal, 34.adjustedW)
214+
}
211215
}
212216
}
213217
}

0 commit comments

Comments
 (0)