Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ struct SelectedTreatmentView: View {
return contentHeight + 24.adjustedH
}

@State private var topGlobalY: CGFloat = .zero
@State private var initialTopGlobalY: CGFloat? = nil
@State private var bottomOffsetY: CGFloat = .zero
Comment on lines +24 to +26
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

옵셔널 nil 초기화 제거로 린트 경고 해소

SwiftLint의 redundant_optional_initialization 경고가 나옵니다. = nil을 제거해도 동작은 동일합니다.

♻️ 제안 변경
-    `@State` private var initialTopGlobalY: CGFloat? = nil
+    `@State` private var initialTopGlobalY: CGFloat?
📝 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.

Suggested change
@State private var topGlobalY: CGFloat = .zero
@State private var initialTopGlobalY: CGFloat? = nil
@State private var bottomOffsetY: CGFloat = .zero
`@State` private var topGlobalY: CGFloat = .zero
`@State` private var initialTopGlobalY: CGFloat?
`@State` private var bottomOffsetY: CGFloat = .zero
🧰 Tools
🪛 SwiftLint (0.57.0)

[Warning] 25-25: Initializing an optional variable with nil is redundant

(redundant_optional_initialization)

🤖 Prompt for AI Agents
In
`@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/Components/SelectedTreatmentView.swift`
around lines 24 - 26, The SwiftLint warning is caused by the redundant optional
initialization on the `@State` property initialTopGlobalY; remove the explicit "=
nil" so it reads "@State private var initialTopGlobalY: CGFloat?" to satisfy the
redundant_optional_initialization rule, leaving topGlobalY and bottomOffsetY
unchanged and ensure no other code relies on the explicit "= nil" initializer
for initialTopGlobalY.


var body: some View {
VStack(spacing: 0) {
VStack(spacing: 0) {
Expand All @@ -46,24 +50,86 @@ struct SelectedTreatmentView: View {
x: 0,
y: -5
)
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: spacing) {
ForEach(selectedTreatments, id: \.id) { treatment in
TreatmentRowView(
displayMode: .summary,
treatmentEntity: treatment,
isSelected: .constant(true),
action: { removeTreatment(treatment) }
)
.frame(height: itemHeight)
ZStack {
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: spacing) {
scrollViewTopMarkerView
.allowsHitTesting(false)

ForEach(selectedTreatments, id: \.id) { treatment in
TreatmentRowView(
displayMode: .summary,
treatmentEntity: treatment,
isSelected: .constant(true),
action: { removeTreatment(treatment) }
)
.frame(height: itemHeight)
}

scrollViewBottomMarkerView
.allowsHitTesting(false)
}
.padding(.vertical, 14.adjustedH)
}
.padding(.vertical, 14.adjustedH)

GradientBox(isTop: true)
.frame(height: 42)
.allowsHitTesting(false)
.opacity(shouldShowGradientTop ? 1 : 0)
.frame(maxHeight: .infinity, alignment: .top)

GradientBox(isTop: false)
.frame(height: 42)
.allowsHitTesting(false)
.opacity(shouldShowGradientBottom ? 1 : 0)
.frame(maxHeight: .infinity, alignment: .bottom)
}
.frame(height: scrollViewHeight)
.scrollDisabled(selectedTreatments.count <= maxVisibleCount)
.padding(.horizontal, 24.5.adjustedW)
.coordinateSpace(name: "SelectedTreatmentScroll")
.onPreferenceChange(ScrollTopPreferenceKey.self) { minY in
if initialTopGlobalY == nil { initialTopGlobalY = minY }
topGlobalY = minY
}
.onPreferenceChange(ScrollBottomPreferenceKey.self) { height in
bottomOffsetY = height
}
}
}
}

extension SelectedTreatmentView {
private var scrollViewTopMarkerView: some View {
GeometryReader { proxy in
Color.clear
.preference(
key: ScrollTopPreferenceKey.self,
value: proxy.frame(in: .named("SelectedTreatmentScroll")).minY
)
}
.frame(height: 0)
}

private var scrollViewBottomMarkerView: some View {
GeometryReader { proxy in
Color.clear
.preference(
key: ScrollBottomPreferenceKey.self,
value: proxy.frame(in: .named("SelectedTreatmentScroll")).maxY
)
}
.frame(height: 0)
}

private var shouldShowGradientTop: Bool {
guard selectedTreatments.count > maxVisibleCount else { return false }
guard let initial = initialTopGlobalY else { return false }
return topGlobalY < initial - 1
}

private var shouldShowGradientBottom: Bool {
let remaining = bottomOffsetY - scrollViewHeight.adjustedH
return remaining > 1
Comment on lines +131 to +133
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

하단 그라디언트가 비스크롤 상태에서도 노출될 수 있습니다

scrollViewHeight는 이미 adjustedH가 반영된 값인데 다시 adjustedH를 적용하고, 비스크롤 상태 가드가 없어 패딩 차이로 하단 그라디언트가 항상 보일 수 있습니다. 조건을 보강해 주세요.

🐛 제안 변경
-    private var shouldShowGradientBottom: Bool {
-        let remaining = bottomOffsetY - scrollViewHeight.adjustedH
-        return remaining > 1
-    }
+    private var shouldShowGradientBottom: Bool {
+        guard selectedTreatments.count > maxVisibleCount else { return false }
+        let remaining = bottomOffsetY - scrollViewHeight
+        return remaining > 1
+    }
🤖 Prompt for AI Agents
In
`@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/Treatment/Components/SelectedTreatmentView.swift`
around lines 131 - 133, shouldShowGradientBottom currently reapplies adjustedH
and lacks a non-scroll guard, causing the bottom gradient to appear even when
content isn't scrollable; update the computed property
(shouldShowGradientBottom) to use scrollViewHeight as-is (remove the extra
.adjustedH application) and add a guard that the content is actually scrollable
(e.g., check contentHeight > scrollViewHeight or an isScrollable flag) before
computing remaining = bottomOffsetY - scrollViewHeight, then return remaining >
1; reference the bottomOffsetY, scrollViewHeight, adjustedH and
shouldShowGradientBottom symbols when making the change.

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@ struct TabBarCoordinatorView: View {
}
.padding(.bottom, tabBarCoordinator.isTabbarHidden ? 0 : 54.adjustedH)
.id(tabBarCoordinator.selectedTab)
.environmentObject(tabBarCoordinator)
if !tabBarCoordinator.isTabbarHidden {
CherrishTabBar(selectedTab: $tabBarCoordinator.selectedTab)
}
}
.environmentObject(tabBarCoordinator)
.onChange(of: tabBarCoordinator.selectedTab) { oldTab, newTab in
.onChange(of: tabBarCoordinator.selectedTab) { _, newTab in
switch newTab {
case .home:
tabBarCoordinator.homeCoordinator.popToRoot()
Expand Down