Conversation
📝 WalkthroughWalkthrough챌린지 네비게이션에 Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant SelectRoutineView
participant ChallengeCoordinatorView
participant TabBarCoordinator
participant LoadingView
participant ChallengeProgressView
User->>SelectRoutineView: 루틴 선택 및 Next 탭
SelectRoutineView->>ChallengeCoordinatorView: navigate(to: .loading)
ChallengeCoordinatorView->>TabBarCoordinator: onAppear -> isTabbarHidden = true
ChallengeCoordinatorView->>LoadingView: present .loading
LoadingView-->>ChallengeCoordinatorView: 완료 이벤트
ChallengeCoordinatorView->>ChallengeProgressView: navigate(to: .challengeProgress)
ChallengeProgressView->>TabBarCoordinator: onAppear -> isTabbarHidden = false
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift:
- Around line 17-33: The switch in ChallengeCoordinatorView that calls
ViewFactory.shared.makeChallengeView(), makeStartChallengeView(),
makeSelectRoutineView(), makeLoadingView(), and makeSelectMissionView() repeats
.navigationBarBackButtonHidden() for every case; refactor by applying
.navigationBarBackButtonHidden() once to the entire navigationDestination result
(or wrap the created views in a single ViewModifier) so each case returns the
raw view from ViewFactory.shared.* without the modifier and the modifier is
applied once outside the switch.
- Line 36: The NavigationStack currently uses .ignoresSafeArea(.all), which can
let child views like StartChallengeView render under notches/Dynamic Island and
bypass their fixed padding (e.g., 84.adjustedH); change the NavigationStack to
stop ignoring all safe areas (either remove .ignoresSafeArea(.all) or restrict
it to a specific edge such as .ignoresSafeArea(.container, edges: .bottom) ),
and update child views (StartChallengeView and other descendants) to respect
safe area insets by using safe-area-aware padding or reading safeAreaInsets
(replace fixed top padding with a safeArea-based padding) so content cannot be
obscured on devices with Dynamic Island/notches.
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift:
- Line 23: Remove the redundant explicit nil assignment on the optional state
property by changing the declaration of selectedRoutine in SelectRoutineView
(the @State private var selectedRoutine: RoutineType? = nil line) to omit "=
nil" so it relies on Swift's default nil initialization for optional types.
- Around line 12-17: Enum declaration "RoutineType" is missing a space before
the opening brace; update the enum definition (enum RoutineType) to follow Swift
style by adding a single space before the "{" so it reads "enum RoutineType {",
keeping the existing cases unchanged.
- Around line 36-46: The HStack and VStack declarations lack a space before
their opening braces; update the UI container declarations (HStack and
VStack(alignment: .leading)) to follow Swift style by inserting a space before
the `{` (e.g., change "HStack{" and "VStack(alignment: .leading){" to include a
space), ensuring consistent formatting across the SelectRoutineView.swift
snippet.
- Around line 8-11: Remove the duplicate import by keeping a single "import
SwiftUI" at the top of SelectRoutineView (the SelectRoutineView struct/file) and
delete the extra duplicate import statement so SwiftUI is only imported once;
verify there are no other duplicate import lines in that file.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swiftCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
🧰 Additional context used
🧬 Code graph analysis (1)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift (3)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Shadow.swift (1)
body(9-17)Cherrish-iOS/Cherrish-iOS/Presentation/Coordinator/AppCoordinatorProtocol.swift (1)
pop(22-24)Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Color.swift (1)
gray1000(49-51)
🪛 SwiftLint (0.57.0)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
[Warning] 10-10: Imports should be unique
(duplicate_imports)
[Warning] 23-23: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
🔇 Additional comments (3)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift (3)
30-35:VStack()의 빈 괄호를 제거하고, 네비게이션 버튼 동작을 확인하세요.
VStack()의 빈 괄호는 불필요합니다.- PR 설명에 따르면 뒤로가기 버튼과 X 버튼의 네비게이션 동작이 다르게 보이는데 (two-step back navigation), 현재
leftButtonAction과rightButtonAction이 동일하게pop을 호출하고 있습니다. X 버튼은 챌린지 플로우 전체를 닫는 동작이 의도된 것인지 확인이 필요합니다.♻️ VStack 수정 제안
- VStack() { + VStack { CherrishNavigationBar(
48-59: 루틴 칩 그리드 레이아웃이 잘 구현되었습니다.4개의 루틴 타입을 2x2 그리드로 배치하고, 일관된 spacing과 padding을 적용한 구현이 깔끔합니다.
72-77:routineChip헬퍼 함수가 단일 선택 로직을 잘 캡슐화했습니다.커스텀 Binding을 사용하여 선택 상태를 중앙에서 관리하는 패턴이 적절합니다. getter와 setter를 통해
selectedRoutine과 각 칩의 상태를 동기화하는 방식이 명확합니다.
...S/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift
Outdated
Show resolved
Hide resolved
...S/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift
Outdated
Show resolved
Hide resolved
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
Outdated
Show resolved
Hide resolved
| HStack{ | ||
| VStack(alignment: .leading){ | ||
| TypographyText("지금 나에게 가장 필요한\n관리 루틴을 선택해주세요.", | ||
| style: .title1_sb_18, | ||
| color: .gray1000 | ||
| ) | ||
| } | ||
| Spacer() | ||
| } | ||
| .padding(.top, 80.adjustedH) | ||
| .padding(.horizontal, 33.adjustedW) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
중괄호 앞에 공백을 추가하세요.
Swift 스타일 가이드에 따라 HStack{과 VStack(alignment: .leading){ 뒤에 공백이 필요합니다.
♻️ 수정 제안
- HStack{
- VStack(alignment: .leading){
+ HStack {
+ VStack(alignment: .leading) {
TypographyText("지금 나에게 가장 필요한\n관리 루틴을 선택해주세요.",
style: .title1_sb_18,
color: .gray1000
)
}
Spacer()
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| HStack{ | |
| VStack(alignment: .leading){ | |
| TypographyText("지금 나에게 가장 필요한\n관리 루틴을 선택해주세요.", | |
| style: .title1_sb_18, | |
| color: .gray1000 | |
| ) | |
| } | |
| Spacer() | |
| } | |
| .padding(.top, 80.adjustedH) | |
| .padding(.horizontal, 33.adjustedW) | |
| HStack { | |
| VStack(alignment: .leading) { | |
| TypographyText("지금 나에게 가장 필요한\n관리 루틴을 선택해주세요.", | |
| style: .title1_sb_18, | |
| color: .gray1000 | |
| ) | |
| } | |
| Spacer() | |
| } | |
| .padding(.top, 80.adjustedH) | |
| .padding(.horizontal, 33.adjustedW) |
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
around lines 36 - 46, The HStack and VStack declarations lack a space before
their opening braces; update the UI container declarations (HStack and
VStack(alignment: .leading)) to follow Swift style by inserting a space before
the `{` (e.g., change "HStack{" and "VStack(alignment: .leading){" to include a
space), ensuring consistent formatting across the SelectRoutineView.swift
snippet.
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift:
- Around line 27-41: Duplicate tab bar hide logic appears in the switch cases
for selectRoutine, loading, and selectMission; centralize this by extracting the
hide behavior into one place: create a helper (e.g., a computed Bool or method
like shouldHideTabbar(for: currentRoute) or a ViewModifier hideTabbar()) and use
it to set tabBarCoordinator.isTabbarHidden = true once based on the route
instead of repeating it in each case; update references in
ChallengeCoordinatorView (cases selectRoutine, loading, selectMission) to rely
on that shared helper so future routes can be added by updating the single
list/logic.
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift:
- Line 25: Fix the incomplete SwiftUI padding call in LoadingView: replace
`.padding(.horizontal,)` with either a no-value edge-only call
`.padding(.horizontal)` or provide a concrete CGFloat value like
`.padding(.horizontal, 16)` (choose whichever fits the intended layout) so the
code compiles; update the modifier on the view in LoadingView.swift accordingly.
- Around line 14-37: The VStack that starts at the top is closed too early (the
closing brace after .padding(.top, 113.adjustedH)); move that closing brace so
that Image(.loading), the following TypographyText calls, Spacer(), and the
final TypographyText are all inside the same outer VStack that contains
CherrishNavigationBar; also remove the stray trailing comma in
.padding(.horizontal,) and keep existing symbols:
CherrishNavigationBar(isDisplayRightButton:false, leftButtonAction:
challengeCoordinator.pop), the inner VStack with TypographyText lines,
Image(.loading), TypographyText("잠시만 기다려주세요!"), Spacer(), and
TypographyText("AI가 맞춤형 루틴을 제작하고 있어요.") so the layout renders as a single
vertical stack.
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift:
- Line 21: Remove the redundant explicit nil initialization for the Optional
state property by changing the declaration of selectedRoutine so it relies on
Swift’s default nil for optionals; update the @State variable named
selectedRoutine: RoutineType? to omit the “= nil” initializer to satisfy
SwiftLint and simplify the code.
- Around line 10-15: Make RoutineType conform to CaseIterable and add a computed
property (e.g., koreanTitle or localizedTitle) that returns the Korean display
string for each case (skinCondition, lifeStyle, bodyShaping, wellness) so
callers can iterate all cases and get a human-readable title; update any UI code
that displays RoutineType to use this computed property instead of hardcoded
strings.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
Cherrish-iOS/Cherrish-iOS/Assets.xcassets/ChallengeImage/loading.imageset/loading.svgis excluded by!**/*.svg
📒 Files selected for processing (8)
Cherrish-iOS/Cherrish-iOS/Assets.xcassets/ChallengeImage/loading.imageset/Contents.jsonCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/ChallengeProgressView.swiftCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/ChallengeView.swiftCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinator.swiftCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swiftCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swiftCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swiftCherrish-iOS/Cherrish-iOS/Presentation/ViewFactory.swift
🧰 Additional context used
🧬 Code graph analysis (4)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/ChallengeProgressView.swift (1)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Shadow.swift (1)
body(9-17)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift (1)
Cherrish-iOS/Cherrish-iOS/Presentation/ViewFactory.swift (6)
makeStartChallengeView(62-64)makeChallengeView(50-52)makeSelectRoutineView(66-68)makeLoadingView(74-76)makeSelectMissionView(70-72)makeChallengeProgressView(78-80)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift (4)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Shadow.swift (1)
body(9-17)Cherrish-iOS/Cherrish-iOS/Presentation/Coordinator/AppCoordinatorProtocol.swift (1)
pop(22-24)Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Color.swift (1)
gray1000(49-51)Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinator.swift (1)
push(24-26)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift (3)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Shadow.swift (1)
body(9-17)Cherrish-iOS/Cherrish-iOS/Presentation/Coordinator/AppCoordinatorProtocol.swift (1)
pop(22-24)Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Color.swift (3)
red700(89-91)gray800(41-43)gray600(33-35)
🪛 SwiftLint (0.57.0)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
[Warning] 21-21: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
🔇 Additional comments (12)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/ChallengeView.swift (1)
5-5: LGTM!헤더의 작성자 정보가 업데이트되었습니다. 기능적 변경 사항은 없습니다.
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/ChallengeProgressView.swift (1)
10-14: LGTM!ChallengeProgressView의 기본 구조가 프로젝트 컨벤션에 맞게 작성되었습니다. 현재는 플레이스홀더 구현이며, 추후 실제 UI 구현이 필요할 것으로 보입니다.
Cherrish-iOS/Cherrish-iOS/Presentation/ViewFactory.swift (2)
22-22: LGTM!프로토콜에
makeChallengeProgressView()메서드가 올바르게 선언되었습니다. 기존 팩토리 메서드들과 일관된 패턴을 따르고 있습니다.
77-80: LGTM!
makeChallengeProgressView()구현이HomeView,ChallengeView등 다른 간단한 뷰들과 동일한 패턴을 따르고 있습니다. 추후 ViewModel이 필요해지면OnboardingView처럼 DIContainer를 통한 주입 패턴으로 확장할 수 있습니다.Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinator.swift (1)
16-16: 라우트 구현 완료 확인됨새로운
challengeProgress라우트 케이스가 ChallengeCoordinator에서 정의되었으며, ChallengeCoordinatorView에서도 올바르게 처리되고 있습니다. ViewFactory를 통해 ChallengeProgressView를 생성하고 navigationBarBackButtonHidden()을 적용하는 기존 패턴과 일치합니다.Cherrish-iOS/Cherrish-iOS/Assets.xcassets/ChallengeImage/loading.imageset/Contents.json (1)
1-12: 에셋 구성이 올바릅니다.Xcode 에셋 카탈로그 형식이 정확하며,
loading.svg파일이 올바른 위치에 존재합니다. 이미지셋 디렉토리 구조가 완벽합니다.Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift (2)
42-48: challengeProgress 경로 추가 확인
challengeProgress경로에서 탭바를 다시 표시하는 로직이 올바르게 구현되었습니다. 챌린지 진행 화면에서 탭바가 보여야 하는 요구사항에 부합합니다.
52-52: ignoresSafeArea(.all) 적용 범위 확인 필요전체 NavigationStack에
.ignoresSafeArea(.all)을 적용하면 노치/홈 인디케이터 영역까지 콘텐츠가 확장됩니다. 각 하위 뷰에서 safe area를 개별적으로 처리해야 하므로, 의도된 동작인지 확인이 필요합니다.Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift (1)
15-18: 네비게이션 바 설정 확인
isDisplayRightButton: false로 오른쪽 버튼을 숨기고, 왼쪽 버튼은pop동작으로 설정되어 있습니다. 로딩 화면에서 사용자가 뒤로 가기를 할 수 있어야 하는지 UX 관점에서 확인이 필요합니다. 로딩 중 네비게이션을 허용하면 예기치 않은 상태가 발생할 수 있습니다.Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift (3)
29-33: 좌/우 버튼 동작 동일 여부 확인
leftButtonAction과rightButtonAction모두challengeCoordinator.pop을 호출합니다. PR 설명에서 뒤로가기 버튼과 X 버튼의 네비게이션 동작이 다르다고 언급되어 있는데, 현재 구현은 동일한 동작을 수행합니다. 의도된 동작인지 확인이 필요합니다.
71-75: routineChip 헬퍼 함수 구현 우수
Binding의 getter/setter를 활용하여 단일 선택 동작을 깔끔하게 구현했습니다.SelectionChip은 Bool만 받고,SelectRoutineView가 어떤RoutineType이 선택되었는지 중앙에서 관리하는 구조가 좋습니다.
61-63: 버튼 상태 바인딩 확인
CherrishButton에.constant(nextButtonState)를 사용하고 있습니다. 만약CherrishButton이 내부적으로 state를 변경하지 않는다면 괜찮지만, 변경이 필요한 경우.constant대신@Binding을 사용해야 합니다.
| .onAppear() { | ||
| tabBarCoordinator.isTabbarHidden = true | ||
| } | ||
| case .loading: | ||
| ViewFactory.shared.makeLoadingView() | ||
| .navigationBarBackButtonHidden() | ||
| .onAppear() { | ||
| tabBarCoordinator.isTabbarHidden = true | ||
| } | ||
| case .selectMission: | ||
| ViewFactory.shared.makeSelectMissionView() | ||
| .navigationBarBackButtonHidden() | ||
| .onAppear() { | ||
| tabBarCoordinator.isTabbarHidden = true | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
탭바 숨김 로직 중복
selectRoutine, loading, selectMission 세 곳에서 동일한 isTabbarHidden = true 로직이 반복됩니다. 현재는 괜찮지만, 향후 경로가 추가될 때 유지보수를 위해 탭바를 숨겨야 하는 경로를 별도로 관리하는 방식을 고려해볼 수 있습니다.
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift
around lines 27 - 41, Duplicate tab bar hide logic appears in the switch cases
for selectRoutine, loading, and selectMission; centralize this by extracting the
hide behavior into one place: create a helper (e.g., a computed Bool or method
like shouldHideTabbar(for: currentRoute) or a ViewModifier hideTabbar()) and use
it to set tabBarCoordinator.isTabbarHidden = true once based on the route
instead of repeating it in each case; update references in
ChallengeCoordinatorView (cases selectRoutine, loading, selectMission) to rely
on that shared helper so future routes can be added by updating the single
list/logic.
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift
Show resolved
Hide resolved
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift
Outdated
Show resolved
Hide resolved
| enum RoutineType{ | ||
| case skinCondition | ||
| case lifeStyle | ||
| case bodyShaping | ||
| case wellness | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
RoutineType enum 개선 제안
enum이 잘 정의되어 있습니다. 향후 확장성을 위해 CaseIterable 프로토콜 채택과 한글 타이틀을 위한 computed property 추가를 고려해보세요.
♻️ 개선 제안
-enum RoutineType{
+enum RoutineType: CaseIterable {
case skinCondition
case lifeStyle
case bodyShaping
case wellness
+
+ var title: String {
+ switch self {
+ case .skinCondition: return "피부 컨디션"
+ case .lifeStyle: return "생활습관"
+ case .bodyShaping: return "체형 관리"
+ case .wellness: return "웰니스∙마음챙김"
+ }
+ }
}🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
around lines 10 - 15, Make RoutineType conform to CaseIterable and add a
computed property (e.g., koreanTitle or localizedTitle) that returns the Korean
display string for each case (skinCondition, lifeStyle, bodyShaping, wellness)
so callers can iterate all cases and get a human-readable title; update any UI
code that displays RoutineType to use this computed property instead of
hardcoded strings.
|
|
||
| @EnvironmentObject private var challengeCoordinator: ChallengeCoordinator | ||
|
|
||
| @State private var selectedRoutine: RoutineType? = nil |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Optional 변수의 nil 초기화 중복
SwiftLint 경고: Optional 변수를 nil로 초기화하는 것은 중복입니다. Swift에서 Optional은 기본값이 nil입니다.
♻️ 수정 제안
- @State private var selectedRoutine: RoutineType? = nil
+ @State private var selectedRoutine: RoutineType?📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @State private var selectedRoutine: RoutineType? = nil | |
| @State private var selectedRoutine: RoutineType? |
🧰 Tools
🪛 SwiftLint (0.57.0)
[Warning] 21-21: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
at line 21, Remove the redundant explicit nil initialization for the Optional
state property by changing the declaration of selectedRoutine so it relies on
Swift’s default nil for optionals; update the @State variable named
selectedRoutine: RoutineType? to omit the “= nil” initializer to satisfy
SwiftLint and simplify the code.
soseoyo12
left a comment
There was a problem hiding this comment.
어푸푸푸푸푸푸 익사하겠다 수고하셨습니다~
wotjs020708
left a comment
There was a problem hiding this comment.
고생하셨습니담 코멘트 확인 부탁드려욤
y-eonee
left a comment
There was a problem hiding this comment.
루틴 선택 토글안되게 하고 최근선택으로 들어가게만 수정해주면 될 것 같아요 수고하셨습니당
| HStack(spacing:0) { | ||
| TypographyText("피부 컨디션", style: .title1_sb_18, color: .red700) | ||
| TypographyText(" 관리 방향을 바탕으로", style: .title1_sb_18, color: .gray800) |
There was a problem hiding this comment.
이 방법보다는 일부 텍스트만 컬러를 바꿀 수 있도록 익스텐션이나 다른 방법을 찾아보는게 좋을 것 같아요!!
| Image(.loading) | ||
| .padding(.top, 17.adjustedH) | ||
| TypographyText("잠시만 기다려주세요!", style: .title2_sb_16, color: .gray800) | ||
| .padding(.top, 17.adjustedH) | ||
| Spacer() | ||
| TypographyText("AI가 맞춤형 루틴을 제작하고 있어요.", style: .body3_m_12, color: .gray600) | ||
| .padding(.bottom, 30.adjustedH) |
| case lifeStyle | ||
| case bodyShaping | ||
| case wellness | ||
| } |
There was a problem hiding this comment.
밑에 따로 타이틀을 하드코딩해두는 것보다는 여기서 변수로 작성해서 사용하는 것이 좋을 것 같아요
| SelectionChip(title: title, isSelected: Binding(get: {selectedRoutine == type}, | ||
| set: {isSelected in selectedRoutine = isSelected ? type : nil})) |
There was a problem hiding this comment.
요기 isSelected에서 개행한번만 해주세여
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In
`@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift`:
- Around line 35-45: The View extension named
highlight(highlightText:highlightColor:normalText:) is declared globally but
lives inside LoadingView.swift; either restrict its scope by changing it to a
private extension (private extension View { func highlight(...) -> some View {
... } }) if it’s only used in this file, or move the extension to a new shared
file (e.g., View+Highlight.swift) under your Global/Extension folder for
app-wide reuse; update call sites to use the same signature and keep the inner
implementation using TypographyText(highlightText, ...) unchanged.
♻️ Duplicate comments (3)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift (2)
34-34: Optional 변수의 중복 nil 초기화를 제거하세요.Swift에서 Optional 타입은 기본값이
nil이므로 명시적인 초기화가 불필요합니다.♻️ 수정 제안
- `@State` private var selectedRoutine: RoutineType? = nil + `@State` private var selectedRoutine: RoutineType?
47-48: 중괄호 앞에 공백을 추가하세요.Swift 스타일 가이드에 따라
HStack{과VStack(alignment: .leading){앞에 공백이 필요합니다.♻️ 수정 제안
- HStack{ - VStack(alignment: .leading){ + HStack { + VStack(alignment: .leading) {Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift (1)
14-32: 레이아웃 구조 오류: VStack이 조기에 닫혀 있습니다.Line 24에서 VStack이 닫히지만
Image(.loading),TypographyText,Spacer등의 요소들이 VStack 외부에 위치해 있습니다. SwiftUI의body는 단일 View를 반환해야 하므로 컴파일 오류가 발생하거나 의도치 않은 레이아웃이 됩니다.🐛 수정 제안: 모든 요소를 하나의 VStack으로 감싸기
var body: some View { VStack(alignment: .center) { CherrishNavigationBar( isDisplayRightButton:false, leftButtonAction: challengeCoordinator.pop ) VStack { highlight(highlightText: "피부 컨디션", normalText: "관리 방향을 바탕으로") TypographyText("TODO 미션을 만들고 있어요.", style: .title1_sb_18, color: .gray800) } .padding(.top, 113.adjustedH) - } - Image(.loading) + Image(.loading) - .padding(.top, 17.adjustedH) + .padding(.top, 17.adjustedH) - TypographyText("잠시만 기다려주세요!", style: .title2_sb_16, color: .gray800) + TypographyText("잠시만 기다려주세요!", style: .title2_sb_16, color: .gray800) - .padding(.top, 17.adjustedH) + .padding(.top, 17.adjustedH) - Spacer() + Spacer() - TypographyText("AI가 맞춤형 루틴을 제작하고 있어요.", style: .body3_m_12, color: .gray600) + TypographyText("AI가 맞춤형 루틴을 제작하고 있어요.", style: .body3_m_12, color: .gray600) - .padding(.bottom, 30.adjustedH) + .padding(.bottom, 30.adjustedH) + } }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swiftCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swiftCherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
🧰 Additional context used
🧬 Code graph analysis (2)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift (1)
Cherrish-iOS/Cherrish-iOS/Presentation/ViewFactory.swift (6)
makeStartChallengeView(62-64)makeChallengeView(50-52)makeSelectRoutineView(66-68)makeLoadingView(74-76)makeSelectMissionView(70-72)makeChallengeProgressView(78-80)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift (3)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Shadow.swift (1)
body(9-17)Cherrish-iOS/Cherrish-iOS/Presentation/Coordinator/AppCoordinatorProtocol.swift (1)
pop(22-24)Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/View+Color.swift (3)
gray800(41-43)gray600(33-35)red700(89-91)
🪛 SwiftLint (0.57.0)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift
[Warning] 34-34: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
🔇 Additional comments (3)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/Coordinator/ChallengeCoordinatorView.swift (1)
17-45: LGTM! 이전 리뷰 피드백이 잘 반영되었습니다.
Group으로 감싸고.navigationBarBackButtonHidden()을 한 번만 적용한 리팩토링이 적절합니다. 경로별 탭바 가시성 관리도onAppear를 통해 올바르게 구현되었습니다.Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/SelectRoutineView.swift (2)
83-92: 단일 선택 로직이 잘 구현되었습니다.
Binding을 활용한 칩 선택 관리가 적절합니다.guard isSelected else { return }로직으로 인해 이미 선택된 칩을 다시 탭해도 선택 해제되지 않습니다. 다른 칩을 선택해야만 변경되는 동작이 의도된 것이라면 현재 구현이 적합합니다.
10-28: RoutineType enum이 잘 정의되었습니다.각 케이스에 대한
titlecomputed property가 적절하게 구현되어 UI에서 하드코딩을 피할 수 있습니다. 향후 확장성을 위해CaseIterable프로토콜 채택을 고려해볼 수 있습니다.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| extension View { | ||
| func highlight( | ||
| highlightText: String, | ||
| highlightColor: Color = .red700, | ||
| normalText: String | ||
| ) -> some View { | ||
| HStack { | ||
| TypographyText(highlightText, style: .title1_sb_18, color: highlightColor) | ||
| TypographyText(normalText, style: .title1_sb_18, color: .gray800) | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
View extension의 위치를 고려해보세요.
highlight extension이 LoadingView.swift에 정의되어 있지만, extension View로 선언되어 앱 전체에서 사용 가능합니다. 재사용성을 위해 Global/Extension 폴더로 이동하거나, 이 파일에서만 사용한다면 private extension으로 범위를 제한하는 것이 좋습니다.
♻️ 옵션 1: private으로 범위 제한
-extension View {
+private extension View {
func highlight(♻️ 옵션 2: Global/Extension으로 이동
View+Highlight.swift 파일을 Presentation/Global/Extension/ 폴더에 생성하여 다른 View extension들과 일관성을 유지하세요.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| extension View { | |
| func highlight( | |
| highlightText: String, | |
| highlightColor: Color = .red700, | |
| normalText: String | |
| ) -> some View { | |
| HStack { | |
| TypographyText(highlightText, style: .title1_sb_18, color: highlightColor) | |
| TypographyText(normalText, style: .title1_sb_18, color: .gray800) | |
| } | |
| } | |
| private extension View { | |
| func highlight( | |
| highlightText: String, | |
| highlightColor: Color = .red700, | |
| normalText: String | |
| ) -> some View { | |
| HStack { | |
| TypographyText(highlightText, style: .title1_sb_18, color: highlightColor) | |
| TypographyText(normalText, style: .title1_sb_18, color: .gray800) | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
In
`@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/LoadingView.swift`
around lines 35 - 45, The View extension named
highlight(highlightText:highlightColor:normalText:) is declared globally but
lives inside LoadingView.swift; either restrict its scope by changing it to a
private extension (private extension View { func highlight(...) -> some View {
... } }) if it’s only used in this file, or move the extension to a new shared
file (e.g., View+Highlight.swift) under your Global/Extension folder for
app-wide reuse; update call sites to use the same signature and keep the inner
implementation using TypographyText(highlightText, ...) unchanged.
Style/#48 selectroutineview 구현
🔗 연결된 이슈
📄 작업 내용
💻 주요 코드 설명