Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -73,8 +73,8 @@ private struct HeaderLogoView: View {
.frame(width: 116.adjustedW, height: 40.adjustedH)
Spacer()
}
.padding(.leading, 32.adjustedW)
.padding(.top, 40.adjustedH)
.padding(.leading, 25.adjustedW)
.padding(.top, 26.adjustedH)
}
}

Expand All @@ -95,6 +95,8 @@ private struct ChallengeCardEmptyView: View {
.padding(.leading, 18.adjustedW)

Image(challengeBarImageName)
.resizable()
.aspectRatio(contentMode: .fit)
.padding(.top, 10.adjustedH)
.padding(.horizontal, 18.adjustedW)

Expand Down Expand Up @@ -155,7 +157,10 @@ private struct ChallengeCardView: View {
.padding(.leading, 18.adjustedW)

Image(challengeBarImageName)
.resizable()
.aspectRatio(contentMode: .fit)
.padding(.top, 16.adjustedH)
.padding(.horizontal, 18.adjustedW)
}
.frame(height: 131.adjustedH)
.frame(maxWidth: .infinity)
Expand Down Expand Up @@ -242,7 +247,7 @@ private struct PlanBoxView: View {

private var emptyStateView: some View {
HStack {
TypographyText("진행 중인 일정이 없어요", style: .body1_r_14, color: .gray600)
TypographyText("진행 중인 일정이 없어요", style: .body1_m_14, color: .gray600)
Spacer()
}
.padding(.vertical, 12.adjustedH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ struct InformationView: View {
.padding(.horizontal, 25.adjustedW)
.padding(.bottom, 38.adjustedH)
}
.ignoresSafeArea(.keyboard)
.contentShape(Rectangle())
.onTapGesture {
isNameFocused = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct OnboardingContainerView: View {
TabView(selection: $currentPage) {
OnboardingPage1()
.tag(0)
.padding(.bottom, 20.adjustedH)
.padding(.bottom, 40.adjustedH)
OnboardingPage2()
.tag(1)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,38 @@

import SwiftUI

private struct Line1WidthKey: PreferenceKey {
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
Copy link
Member

Choose a reason for hiding this comment

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

이거 제가 PreferenceKey 만들어둔 파일 있는데 거기다가 옮겨주세여

Copy link
Contributor

Choose a reason for hiding this comment

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

이거 써서 높이 구하는 거죠?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

가로 길이 구하는거에여

}



struct OnboardingPage1: View {
@State private var line1Width: CGFloat = 0

var body: some View {
VStack(spacing: 0) {
Image(.illustrationOnboardingCal)
.resizable()
.scaledToFit()
.frame(width: 294.adjustedW)
.frame(width: 294.adjustedW, height: 254.adjustedH)
.overlay(alignment: .topLeading) {
Image(.illustrationOnboardingCh)
.resizable()
.scaledToFit()
.frame(width: 152.adjustedW)
.offset(x: 152.adjustedW, y: 180.adjustedH)
.frame(width: 152.adjustedW, height: 204.adjustedH)
.offset(x: 152.adjustedW, y: 209.adjustedH)
}
.padding(.top, 92.adjustedH)
.padding(.top, 102.adjustedH)

HStack(spacing: 0) {
Image(.comment)
.resizable()
.scaledToFit()
.frame(width: 100.adjustedW)
.frame(width: 100.adjustedW, height: 44.adjustedH)
.padding(.top, 120.adjustedH)
.padding(.leading, 30.adjustedW)

Expand All @@ -40,20 +51,34 @@ struct OnboardingPage1: View {

Rectangle()
.fill(Color.red700)
.frame(width: 252.adjustedW, height: 1.4)
.frame(width: line1Width, height: 1.4)
.padding(.leading, 4.adjustedW)
Rectangle()
.fill(Color.red700)
.frame(width: 260.adjustedW, height: 1.4)
.fill(Color.red700)
.frame(width: line1Width + 8, height: 1.4)
.padding(.top, 3.adjustedH)

TypographyText("일정을 한 눈에 정리해드려요", style: .title1_sb_18, color: .gray1000)
.padding(.top, 6.adjustedH)
}
.padding(.top, 7.adjustedH)
.frame(maxWidth: .infinity)
.background(
VStack(alignment: .leading, spacing: 0) {
TypographyText("시술 후 불편감이 남을 수 있는 기간", style: .title1_sb_18, color: .clear)
.background(
GeometryReader { geometry in
Color.clear.preference(key: Line1WidthKey.self, value: geometry.size.width)
}
)
}
.opacity(0)
Comment on lines +56 to +65
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the OnboardingPage1.swift file
find . -name "OnboardingPage1.swift" -type f

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 151


🏁 Script executed:

#!/bin/bash
# Read the OnboardingPage1.swift file to see the code context around lines 65-74
sed -n '55,85p' "./Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/OnboardingPage1.swift" | cat -n

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 1567


🏁 Script executed:

#!/bin/bash
# Check the full file to see if there are any other accessibility configurations
grep -n "accessibilityHidden\|isHidden\|accessibility" "./Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/OnboardingPage1.swift"

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 52


🌐 Web query:

SwiftUI opacity accessibility hidden VoiceOver separate from visual rendering

💡 Result:

Short answer: setting .opacity(0) only changes visual rendering — it does not reliably remove a SwiftUI view from the accessibility tree or stop it receiving hits. To keep a view visually present/transparent but hide it from VoiceOver and user interaction, combine accessibility and interaction modifiers (or remove the view from the tree). Example:

  • Hide from VoiceOver: .accessibilityHidden(true) or wrap in a container and use .accessibilityElement(children: .ignore/.combine) as appropriate. [1][2]
  • Prevent taps/gestures: .allowsHitTesting(false) or .disabled(true). [3]
  • If you need the view completely gone (no layout space), conditionally remove it with if/else rather than using opacity. [4]

Example:

MyView()
  .opacity(0)                 // visual transparency
  .accessibilityHidden(true)  // hide from VoiceOver
  .allowsHitTesting(false)    // disable interaction

References:
[1] SwiftUI accessibility modifiers (accessibilityHidden / accessibilityElement).
[2] Guide/discussion on hiding elements for VoiceOver and using .accessibilityElement(children: .ignore/.combine).
[3] Practical advice to combine .opacity(0) with .disabled / .allowsHitTesting to stop interaction (StackOverflow).
[4] Notes on .hidden()/.opacity vs removing view (layout and accessibility differences).


🏁 Script executed:

#!/bin/bash
# Verify the exact line numbers by checking the file again more precisely
wc -l "./Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/OnboardingPage1.swift"

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 154


🏁 Script executed:

#!/bin/bash
# Get the exact lines 65-74 to verify the line numbers in the review comment
sed -n '65,74p' "./Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/OnboardingPage1.swift" | cat -n

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 662


숨겨진 측정 텍스트가 VoiceOver에 노출됩니다.

opacity(0)은 시각적 렌더링만 변경하며 접근성 트리에서 제거되지 않아 VoiceOver 사용자에게 보이지 않는 텍스트가 읽혀집니다. 측정용 뷰를 접근성에서 숨기기 위해 .accessibilityHidden(true)을 추가해주세요.

제안 수정
                    }
                    .opacity(0)
+                   .accessibilityHidden(true)
📝 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
.background(
VStack(alignment: .leading, spacing: 0) {
TypographyText("시술 후 불편감이 남을 수 있는 기간", style: .title1_sb_18, color: .clear)
.background(
GeometryReader { geometry in
Color.clear.preference(key: Line1WidthKey.self, value: geometry.size.width)
}
)
}
.opacity(0)
.background(
VStack(alignment: .leading, spacing: 0) {
TypographyText("시술 후 불편감이 남을 수 있는 기간", style: .title1_sb_18, color: .clear)
.background(
GeometryReader { geometry in
Color.clear.preference(key: Line1WidthKey.self, value: geometry.size.width)
}
)
}
.opacity(0)
.accessibilityHidden(true)
🤖 Prompt for AI Agents
In
`@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/OnboardingPage1.swift`
around lines 65 - 74, The hidden measurement view using TypographyText within
the background (GeometryReader setting Line1WidthKey) currently uses .opacity(0)
which leaves it in the accessibility tree and will be read by VoiceOver; update
the background measurement view (the VStack containing TypographyText and
GeometryReader that writes Line1WidthKey) to also call
.accessibilityHidden(true) so the measurement text is excluded from
accessibility without changing layout.

)
.onPreferenceChange(Line1WidthKey.self) { width in
line1Width = width
}
Spacer()
}
.padding(.top, 7.adjustedH)


Spacer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,26 @@ struct OnboardingPage2: View {
var body: some View {
VStack(spacing: 0) {
HStack(spacing: 0) {
TypographyText("원하는 추구미에 도달할 수 있도록\nTO-DO 루틴을 제시해줘요", style: .title1_m_18, color: .gray1000)
TypographyText("원하는 추구미에 도달할 수 있도록\nTO-DO 루틴을 제시해줘요", style: .title1_sb_18, color: .gray1000)
.fixedSize(horizontal: false, vertical: true)

Spacer()
}
.padding(.horizontal, 42.adjustedW)
.padding(.top, 104.adjustedH)
.padding(.top, 124.adjustedH)

Spacer()
.frame(height: 40.adjustedH)

Image(.onboarding2)
.resizable()
.scaledToFit()
.padding(.top, 40.adjustedH)
.frame(width: 293.adjustedW, height: 202.adjustedH)
.padding(.horizontal, 41.adjustedW)

InfiniteLevelCarousel(levelImages: levelImages, animationDuration: animationDuration)
.frame(height: 89.adjustedH)
.padding(.top, 20.adjustedH)
.padding(.top, 12.adjustedH)

TypographyText("TO-DO 미션을 채울때마다 아리가 변화해요!", style: .title2_r_16, color: .gray600)
.padding(.top, 30.adjustedH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import UIKit

struct CherrishPicker: View {
@Binding var selection: Int
let range: ClosedRange<Int>
var range: ClosedRange<Int> = 0...30
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "CherrishPicker.swift" -type f

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 149


🏁 Script executed:

cat -n ./Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishPicker.swift

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 7294


프로그래매틱 업데이트 시 range 범위 검증 누락으로 크래시 위험

selectionrange 범위 밖으로 설정될 때, makeUIView(라인 43)와 updateUIView(라인 66)에서 selectRow에 전달하는 row 값이 음수이거나 범위를 초과할 수 있습니다. scrollViewDidScroll(라인 152)에서는 이미 clamping으로 범위를 검증하고 있으나, 프로그래매틱 업데이트 경로에서 이 검증이 누락되어 런타임 오류가 발생할 수 있습니다.

🔧 제안 수정
 func makeUIView(context: Context) -> UIPickerView {
     let picker = UIPickerView()
     picker.delegate = context.coordinator
     picker.dataSource = context.coordinator
     
     picker.subviews.forEach { subview in
         subview.backgroundColor = .clear
     }
     
-    let row = selection - range.lowerBound
+    let rawRow = selection - range.lowerBound
+    let row = max(0, min(rawRow, range.count - 1))
+    if rawRow != row {
+        selection = range.lowerBound + row
+    }
     picker.selectRow(row, inComponent: 0, animated: false)
 func updateUIView(_ uiView: UIPickerView, context: Context) {
     guard !context.coordinator.isScrolling else { return }
     
-    let row = selection - range.lowerBound
+    let rawRow = selection - range.lowerBound
+    let row = max(0, min(rawRow, range.count - 1))
+    if rawRow != row {
+        selection = range.lowerBound + row
+    }
     if uiView.selectedRow(inComponent: 0) != row {
         uiView.selectRow(row, inComponent: 0, animated: true)
     }
 }
🤖 Prompt for AI Agents
In
`@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishPicker.swift`
at line 13, selection이 range 밖으로 설정되면 makeUIView 및 updateUIView에서 selectRow에
전달되는 row가 음수거나 범위를 초과해 크래시가 발생할 수 있으니, makeUIView(...)와 updateUIView(...)에서
selectRow를 호출하기 전에 selection을 range 내로 클램프하거나 검증하여 유효한 Int 인덱스로 변환하세요 (예: let
safeRow = min(max(selection, range.lowerBound), range.upperBound) 형태로),
scrollViewDidScroll과 동일한 검증 로직을 재사용하거나 별도 유틸(예: clampedSelection)으로 추출해 중복 제거하고
selectRow 호출 시 safeRow를 사용하도록 수정하세요.

var width: CGFloat = 74.adjustedW

var body: some View {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
{
"images" : [
{
"filename" : "cherrish_logo.svg",
"idiom" : "universal"
"filename" : "logo.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "logo@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "logo@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
Expand Down

This file was deleted.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"images" : [
{
"filename" : "home_lv.1.png",
"filename" : "home_lv.0.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "home_lv.1@2x.png",
"filename" : "home_lv.0@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "home_lv.1@3x.png",
"filename" : "home_lv.0@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"images" : [
{
"filename" : "home_lv.2.png",
"filename" : "home_lv.1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "home_lv.2@2x.png",
"filename" : "home_lv.1@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "home_lv.2@3x.png",
"filename" : "home_lv.1@3x.png",
Comment on lines +4 to +14
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify home_lv.2.imageset folder contents and file naming

echo "=== Contents of home_lv.2.imageset folder ==="
find . -path "*home_lv.2.imageset*" -type f

echo ""
echo "=== All home_lv related PNG files ==="
find . -name "home_lv*.png" -type f | sort

echo ""
echo "=== home_lv.2.imageset/Contents.json ==="
find . -path "*home_lv.2.imageset/Contents.json" -type f -exec cat {} \;

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 2163


🏁 Script executed:

#!/bin/bash
# Verify Contents.json matches actual files in home_lv.2.imageset

echo "=== Checking if all referenced files in Contents.json exist ==="
IMAGESET_PATH="./Cherrish-iOS/Cherrish-iOS/Resources/Assets.xcassets/home_icon/home_lv.2.imageset"

cd "$IMAGESET_PATH" 2>/dev/null && {
  echo "Referenced files in Contents.json:"
  grep '"filename"' Contents.json | grep -o '"[^"]*\.png"'
  
  echo ""
  echo "Actual PNG files in folder:"
  ls -1 *.png 2>/dev/null
  
  echo ""
  echo "Verification: All referenced files exist?"
  for file in home_lv.1.png home_lv.1@2x.png home_lv.1@3x.png; do
    if [ -f "$file" ]; then
      echo "$file exists"
    else
      echo "$file missing"
    fi
  done
} || echo "Could not access imageset folder"

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 417


명명 규칙 일관성 개선 권장

home_lv.2.imageset 폴더의 파일들이 실제로 home_lv.1.*로 명명되어 있으며, Contents.json에서 정확히 이 파일들을 참조하고 있습니다. 파일이 올바르게 존재하고 참조되므로 이미지 로드에는 문제가 없습니다.

다만 imageset 폴더명과 파일명의 불일치는 유지보수성을 떨어뜨리므로, 일관된 명명 규칙으로 통일하는 것이 권장됩니다. (예: 폴더 내 파일을 home_lv.2.*로 명명하거나 폴더명을 home_lv.1.imageset으로 조정)

🤖 Prompt for AI Agents
In
`@Cherrish-iOS/Cherrish-iOS/Resources/Assets.xcassets/home_icon/home_lv.2.imageset/Contents.json`
around lines 4 - 14, The imageset folder is named home_lv.2.imageset but the
image files it contains are named home_lv.1.png, home_lv.1@2x.png, and
home_lv.1@3x.png, creating a naming mismatch. To resolve this, choose one
approach: either rename all three image files to home_lv.2.png,
home_lv.2@2x.png, and home_lv.2@3x.png to match the folder name and update their
references in Contents.json accordingly, or rename the imageset folder to
home_lv.1.imageset to match the actual file names.

"idiom" : "universal",
"scale" : "3x"
}
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
{
"images" : [
{
"filename" : "comment.svg",
"filename" : "Group 2085667425.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Group 2085667425@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Group 2085667425@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading