From 20da2704d1ca762e0703f795c6c9c88b58917c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Fri, 8 Aug 2025 16:54:37 +0900 Subject: [PATCH 1/3] =?UTF-8?q?Fix:=20=EB=A3=A8=ED=8B=B4=20fetch=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Home/View/HomeView.swift | 2 +- .../Home/ViewModel/HomeViewModel.swift | 72 +++++++++++-------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/Projects/Presentation/Sources/Home/View/HomeView.swift b/Projects/Presentation/Sources/Home/View/HomeView.swift index 79b02243..91df0c67 100644 --- a/Projects/Presentation/Sources/Home/View/HomeView.swift +++ b/Projects/Presentation/Sources/Home/View/HomeView.swift @@ -106,13 +106,13 @@ final class HomeView: BaseViewController { configureGradientBackground() showIndicatorView() viewModel.action(input: .loadNickname) - viewModel.action(input: .fetchRoutines) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) configureNavigationBar(navigationStyle: .hidden) viewModel.action(input: .loadEmotion) + viewModel.action(input: .fetchRoutines) } override func viewDidLayoutSubviews() { diff --git a/Projects/Presentation/Sources/Home/ViewModel/HomeViewModel.swift b/Projects/Presentation/Sources/Home/ViewModel/HomeViewModel.swift index c3e3c8d8..8f62576a 100644 --- a/Projects/Presentation/Sources/Home/ViewModel/HomeViewModel.swift +++ b/Projects/Presentation/Sources/Home/ViewModel/HomeViewModel.swift @@ -99,7 +99,7 @@ final class HomeViewModel: ViewModel { updateRoutineCompletion(updatedRoutine: updatedRoutine) case .refreshSelectedDateRoutine: - fetchRoutines(for: selectedDateSubject.value) + fetchDailyRoutine(for: selectedDateSubject.value) case .selectRoutineSortType(let routineSortType): sortRoutine(routineSortType: routineSortType) @@ -135,17 +135,51 @@ final class HomeViewModel: ViewModel { // MARK: - 루틴 // 루틴들을 불러옵니다. (처음에는 +-1 주, 그 이후에는 1주씩) private func fetchRoutines() { - var startDate = oldestDate - var endDate = latestDate - if routines.isEmpty { - startDate = calendar.date(byAdding: .weekOfYear, value: -1, to: today) ?? today - endDate = calendar.date(byAdding: .weekOfYear, value: 1, to: today) ?? today + oldestDate = calendar.date(byAdding: .weekOfYear, value: -1, to: today) ?? today + latestDate = calendar.date(byAdding: .weekOfYear, value: 1, to: today) ?? today + } + fetchRoutines(startDate: oldestDate, endDate: latestDate) + } + + // 날짜를 선택하고 그 날에 해당하는 루틴을 불러옵니다. + private func selectDate(date: Date) { + selectedDateSubject.send(date) + fetchRoutines() + fetchDailyRoutine(for: date) + } + + private func fetchDailyRoutine(for date: Date) { + if let dailyRoutines = routines[date.convertToString(dateType: .yearMonthDate)] { + routinesSubject.send(dailyRoutines) + return + } + var startDate: Date = Date() + var endDate: Date = Date() + if date < oldestDate { + // 캐싱된 데이터보다 이전의 날짜 조회 시, + startDate = calendar.date(byAdding: .weekOfYear, value: -1, to: oldestDate) ?? oldestDate + endDate = calendar.date(byAdding: .day, value: -1, to: oldestDate) ?? oldestDate oldestDate = startDate + } else if date > latestDate { + // 캐싱된 데이터보다 이후의 날짜 조회 시, + startDate = calendar.date(byAdding: .day, value: 1, to: latestDate) ?? latestDate + endDate = calendar.date(byAdding: .weekOfYear, value: 1, to: latestDate) ?? latestDate latestDate = endDate } + fetchRoutines(startDate: startDate, endDate: endDate) + + if let dailyRoutines = routines[date.convertToString(dateType: .yearMonthDate)] { + routinesSubject.send(dailyRoutines) + return + } else { + routinesSubject.send([]) + } + } + // 서버로부터 루틴들을 불러옵니다.. (루틴 조회 시작 날짜 ~ 루틴 조회 종료 날짜) + private func fetchRoutines(startDate: Date, endDate: Date) { Task { do { let entities = try await routineUseCase.fetchRoutines(startDate: startDate, endDate: endDate) @@ -154,35 +188,11 @@ final class HomeViewModel: ViewModel { } fetchRoutineResultSubject.send(true) } catch { - + // TODO: 에러 처리 } } } - // 날짜를 선택하고 그 날에 해당하는 루틴을 불러옵니다. - private func selectDate(date: Date) { - selectedDateSubject.send(date) - fetchRoutines(for: date) - } - - // 선택한 날의 루틴을 필터링하여 보여줍니다. (oldestDate, latestDate 업데이트) - private func fetchRoutines(for date: Date) { - if date <= oldestDate { - oldestDate = calendar.date(byAdding: .weekOfYear, value: -1, to: date) ?? date - latestDate = calendar.date(byAdding: .day, value: -1, to: date) ?? date - } else if date >= latestDate { - oldestDate = calendar.date(byAdding: .day, value: 1, to: date) ?? date - latestDate = calendar.date(byAdding: .weekOfYear, value: 1, to: date) ?? date - } - - let dateKey = date.convertToString(dateType: .yearMonthDate) - guard let dailyRoutines = routines[dateKey] else { - fetchRoutines() - return - } - routinesSubject.send(dailyRoutines) - } - // 반복 루틴을 삭제합니다. private func deleteAllRoutine() { guard let routineId = selectedRoutineSubject.value?.id From 966002e9fd6a18dc8a5187fa468163f6d6e89e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Fri, 8 Aug 2025 17:19:52 +0900 Subject: [PATCH 2/3] =?UTF-8?q?Fix:=20=EB=A3=A8=ED=8B=B4=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EC=8B=9C,=20=ED=82=A4=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EB=82=B4=EB=A0=A4=EA=B0=80=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/Component/RoutineCreationInputView.swift | 6 ++++++ .../Sources/RoutineCreation/View/RoutineCreationView.swift | 2 ++ 2 files changed, 8 insertions(+) diff --git a/Projects/Presentation/Sources/RoutineCreation/View/Component/RoutineCreationInputView.swift b/Projects/Presentation/Sources/RoutineCreation/View/Component/RoutineCreationInputView.swift index 74c9a418..3564d994 100644 --- a/Projects/Presentation/Sources/RoutineCreation/View/Component/RoutineCreationInputView.swift +++ b/Projects/Presentation/Sources/RoutineCreation/View/Component/RoutineCreationInputView.swift @@ -48,6 +48,7 @@ final class RoutineCreationInputView: UIView { textField.delegate = self textField.textColor = .black textField.font = BitnagilFont.init(style: .body2, weight: .semiBold).font + textField.returnKeyType = .done deleteButton.setImage(BitnagilIcon.deleteIcon, for: .normal) deleteButton.addAction( @@ -102,4 +103,9 @@ extension RoutineCreationInputView: UITextFieldDelegate { } return true } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + return true + } } diff --git a/Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationView.swift b/Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationView.swift index 7a1019ce..5b5a3b88 100644 --- a/Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationView.swift +++ b/Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationView.swift @@ -621,6 +621,8 @@ final class RoutineCreationView: BaseViewController { repeatInfoButton.isSelected = false repeatToolTipView.hideTooltip() } + + view.endEditing(true) } } From 31d0c3b285c935660e19c2fb508b7d3b78344616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Fri, 8 Aug 2025 18:46:44 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Fix:=20=EB=A3=A8=ED=8B=B4=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 키보드 입력 끊김 이슈 수정 - 루틴 반복 선택하지 않아도 등록 활성화 되도록 수정 --- .../View/RecommendedRoutineView.swift | 1 + .../View/ResultRecommendedRoutineView.swift | 1 + .../View/Component/RoutineCreationInputView.swift | 12 +++++------- .../ViewModel/RoutineCreationViewModel.swift | 7 +------ SupportingFiles/Info.plist | 2 ++ 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift b/Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift index 5a86fc1a..c35f123c 100644 --- a/Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift +++ b/Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift @@ -327,6 +327,7 @@ extension RecommendedRoutineView: FloatingMenuViewDelegate { fatalError("routineCreationViewModel 의존성이 등록되지 않았습니다.") } let routineCreationView = RoutineCreationView(viewModel: routineCreationViewModel) + routineCreationView.hidesBottomBarWhenPushed = true self.navigationController?.pushViewController(routineCreationView, animated: true) } } diff --git a/Projects/Presentation/Sources/ResultRecommendedRoutine/View/ResultRecommendedRoutineView.swift b/Projects/Presentation/Sources/ResultRecommendedRoutine/View/ResultRecommendedRoutineView.swift index a8960c73..e4585f69 100644 --- a/Projects/Presentation/Sources/ResultRecommendedRoutine/View/ResultRecommendedRoutineView.swift +++ b/Projects/Presentation/Sources/ResultRecommendedRoutine/View/ResultRecommendedRoutineView.swift @@ -368,6 +368,7 @@ final class ResultRecommendedRoutineView: BaseViewController Bool { - if let text = textField.text { - delegate?.routineCreationInputView(self, didChangeText: text) - } - return true + @objc private func textFieldEditingChanged(_ sender: UITextField) { + delegate?.routineCreationInputView(self, didChangeText: sender.text ?? "") } +} +extension RoutineCreationInputView: UITextFieldDelegate { func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() return true diff --git a/Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift b/Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift index 39d9ef19..977c5af4 100644 --- a/Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift +++ b/Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift @@ -272,12 +272,7 @@ final class RoutineCreationViewModel: ViewModel { guard let name = nameSubject.value, !name.isEmpty, - executionTimeSubject.value != .none, - weekDaySubject.value.count > 0, - subRoutinesSubject - .value - .map({$0.subRoutineName}) - .allSatisfy({$0?.isEmpty == false }) + executionTimeSubject.value != .none else { checkRoutinePublisher.send(false) return diff --git a/SupportingFiles/Info.plist b/SupportingFiles/Info.plist index 9a0ba43f..17b219aa 100644 --- a/SupportingFiles/Info.plist +++ b/SupportingFiles/Info.plist @@ -62,5 +62,7 @@ UILaunchStoryboardName LaunchScreen + UIRequiresFullScreen +