Skip to content

Commit cd7d032

Browse files
committed
Feat: 루틴 수정 적용 범위 화면 구현 (#T3-177)
1 parent 45bf1b6 commit cd7d032

2 files changed

Lines changed: 161 additions & 19 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//
2+
// RoutineEditAlertViewController.swift
3+
// Presentation
4+
//
5+
// Created by 최정인 on 8/21/25.
6+
//
7+
8+
import Shared
9+
import SnapKit
10+
import UIKit
11+
12+
final class RoutineEditAlertViewController: UIViewController {
13+
private enum Layout {
14+
static let horizontalMargin: CGFloat = 24
15+
static let mainLabelTopSpacing: CGFloat = 26
16+
static let mainLabelHeight: CGFloat = 24
17+
static let subLabelTopSpacing: CGFloat = 10
18+
static let applyTodayButtonTopSpacing: CGFloat = 24
19+
static let applyTomorrowButtonTopSpacing: CGFloat = 12
20+
static let buttonHeight: CGFloat = 54
21+
}
22+
23+
private let mainLabel = UILabel()
24+
private let subLabel = UILabel()
25+
private let applyTodayButton = UIButton()
26+
private let applyTomorrowButton = UIButton()
27+
var onDismiss: (() -> Void)?
28+
var goToRoutineCreationView: ((Bool) -> Void)?
29+
30+
override func viewDidLoad() {
31+
super.viewDidLoad()
32+
configureAttribute()
33+
configureLayout()
34+
}
35+
36+
override func viewDidDisappear(_ animated: Bool) {
37+
super.viewDidDisappear(animated)
38+
if isBeingDismissed { onDismiss?() }
39+
}
40+
41+
private func configureAttribute() {
42+
mainLabel.text = "변경한 루틴, 언제 시작할까요?"
43+
mainLabel.font = BitnagilFont(style: .title3, weight: .semiBold).font
44+
mainLabel.textColor = BitnagilColor.gray10
45+
46+
subLabel.text = "변경된 루틴이 반영되는 시점을 선택해 주세요."
47+
subLabel.font = BitnagilFont(style: .body2, weight: .medium).font
48+
subLabel.textColor = BitnagilColor.gray40
49+
50+
var applyTodayButtonConfiguration = UIButton.Configuration.filled()
51+
applyTodayButtonConfiguration.baseBackgroundColor = BitnagilColor.gray10
52+
applyTodayButtonConfiguration.background.cornerRadius = 12
53+
applyTodayButtonConfiguration.attributedTitle = AttributedString(
54+
"당일부터 적용",
55+
attributes: .init([.font: BitnagilFont(style: .body2, weight: .medium).font]))
56+
applyTodayButtonConfiguration.baseForegroundColor = .white
57+
applyTodayButton.configuration = applyTodayButtonConfiguration
58+
applyTodayButton.addAction(
59+
UIAction { [weak self] _ in
60+
self?.dismiss(animated: true) {
61+
self?.goToRoutineCreationView?(false)
62+
}
63+
},
64+
for: .touchUpInside)
65+
66+
var applyTomorrowButtonConfiguration = UIButton.Configuration.filled()
67+
applyTomorrowButtonConfiguration.baseBackgroundColor = BitnagilColor.gray10
68+
applyTomorrowButtonConfiguration.background.cornerRadius = 12
69+
applyTomorrowButtonConfiguration.attributedTitle = AttributedString(
70+
"다음 날부터 적용",
71+
attributes: .init([.font: BitnagilFont(style: .body2, weight: .medium).font]))
72+
applyTomorrowButtonConfiguration.baseForegroundColor = .white
73+
applyTomorrowButton.configuration = applyTomorrowButtonConfiguration
74+
applyTomorrowButton.addAction(
75+
UIAction { [weak self] _ in
76+
self?.dismiss(animated: true) {
77+
self?.goToRoutineCreationView?(false)
78+
}
79+
},
80+
for: .touchUpInside)
81+
}
82+
83+
private func configureLayout() {
84+
view.backgroundColor = .systemBackground
85+
view.addSubview(mainLabel)
86+
view.addSubview(subLabel)
87+
view.addSubview(applyTodayButton)
88+
view.addSubview(applyTomorrowButton)
89+
90+
mainLabel.snp.makeConstraints { make in
91+
make.top.equalToSuperview().offset(Layout.mainLabelTopSpacing)
92+
make.leading.equalToSuperview().offset(Layout.horizontalMargin)
93+
make.height.equalTo(Layout.mainLabelHeight)
94+
}
95+
96+
subLabel.snp.makeConstraints { make in
97+
make.top.equalTo(mainLabel.snp.bottom).offset(Layout.subLabelTopSpacing)
98+
make.leading.equalToSuperview().offset(Layout.horizontalMargin)
99+
make.trailing.equalToSuperview().inset(Layout.horizontalMargin)
100+
}
101+
102+
applyTodayButton.snp.makeConstraints { make in
103+
make.top.equalTo(subLabel.snp.bottom).offset(Layout.applyTodayButtonTopSpacing)
104+
make.leading.equalToSuperview().offset(Layout.horizontalMargin)
105+
make.trailing.equalToSuperview().inset(Layout.horizontalMargin)
106+
make.height.equalTo(Layout.buttonHeight)
107+
}
108+
109+
applyTomorrowButton.snp.makeConstraints { make in
110+
make.top.equalTo(applyTodayButton.snp.bottom).offset(Layout.applyTomorrowButtonTopSpacing)
111+
make.leading.equalToSuperview().offset(Layout.horizontalMargin)
112+
make.trailing.equalToSuperview().inset(Layout.horizontalMargin)
113+
make.height.equalTo(Layout.buttonHeight)
114+
}
115+
}
116+
}

Projects/Presentation/Sources/RoutineList/View/RoutineListViewController.swift

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -148,25 +148,15 @@ final class RoutineListViewController: BaseViewController<RoutineListViewModel>
148148
}
149149
}
150150

151-
private func showRoutineDeleteAlertView() {
152-
let routineDeleteViewController = RoutineDeleteViewController(viewModel: viewModel)
153-
if let sheet = routineDeleteViewController.sheetPresentationController {
154-
sheet.prefersGrabberVisible = false
155-
if #available(iOS 16.0, *) {
156-
sheet.detents = [.custom { _ in 270 }]
157-
} else {
158-
sheet.detents = [.medium()]
159-
}
160-
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
161-
sheet.preferredCornerRadius = 20
162-
}
163-
164-
routineDeleteViewController.onDismiss = { [weak self] in
165-
self?.dimmedView?.removeFromSuperview()
166-
self?.dimmedView = nil
167-
}
168-
169-
present(routineDeleteViewController, animated: true)
151+
private func goToRoutineCreationView(routineId: String, isApplyToday: Bool = true) {
152+
guard let routineCreationViewModel = DIContainer.shared.resolve(type: RoutineCreationViewModel.self)
153+
else { fatalError("routineCreationViewModel 의존성이 등록되지 않았습니다.") }
154+
155+
let routineCreationView = RoutineCreationViewController(
156+
viewModel: routineCreationViewModel,
157+
updateInfo: (routineId, isApplyToday ? .today : .tomorrow))
158+
routineCreationView.hidesBottomBarWhenPushed = true
159+
self.navigationController?.pushViewController(routineCreationView, animated: true)
170160
}
171161
}
172162

@@ -183,6 +173,42 @@ extension RoutineListViewController: RoutineCardViewDelegate {
183173

184174
func routineCardView(_ sender: RoutineCardView, didTapEditButton routine: Routine) {
185175
viewModel.action(input: .seleteRoutine(routine: routine))
176+
177+
guard !routine.repeatDay.isEmpty else {
178+
goToRoutineCreationView(routineId: routine.id)
179+
return
180+
}
181+
182+
dimmedView?.removeFromSuperview()
183+
184+
let newDimmedView = UIView()
185+
newDimmedView.backgroundColor = .black.withAlphaComponent(0.7)
186+
newDimmedView.frame = view.bounds
187+
view.addSubview(newDimmedView)
188+
dimmedView = newDimmedView
189+
190+
let routineEditAlertViewController = RoutineEditAlertViewController()
191+
if let sheet = routineEditAlertViewController.sheetPresentationController {
192+
sheet.prefersGrabberVisible = false
193+
if #available(iOS 16.0, *) {
194+
sheet.detents = [.custom { _ in 250 }]
195+
} else {
196+
sheet.detents = [.medium()]
197+
}
198+
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
199+
sheet.preferredCornerRadius = 20
200+
}
201+
202+
routineEditAlertViewController.onDismiss = { [weak self] in
203+
self?.dimmedView?.removeFromSuperview()
204+
self?.dimmedView = nil
205+
}
206+
207+
routineEditAlertViewController.goToRoutineCreationView = { [weak self] isApplyToday in
208+
self?.goToRoutineCreationView(routineId: routine.id, isApplyToday: isApplyToday)
209+
}
210+
211+
present(routineEditAlertViewController, animated: true)
186212
}
187213

188214
func routineCardView(_ sender: RoutineCardView, didTapDeleteButton routine: Routine) {

0 commit comments

Comments
 (0)