Skip to content

fix: 디자인 QA 반영#181

Merged
clxxrlove merged 29 commits intodevelopfrom
BOOK-268-fix/#175
Aug 20, 2025
Merged

fix: 디자인 QA 반영#181
clxxrlove merged 29 commits intodevelopfrom
BOOK-268-fix/#175

Conversation

@clxxrlove
Copy link
Member

@clxxrlove clxxrlove commented Aug 19, 2025

🔗 관련 이슈

  • Close #

📘 작업 유형

  • ✨ Feature (기능 추가)
  • 🐞 Bugfix (버그 수정)
  • 🔧 Refactor (코드 리팩토링)
  • ⚙️ Chore (환경 설정)
  • 📝 Docs (문서 작성 및 수정)
  • ✅ Test (기능 테스트)
  • 🎨 style (코드 스타일 수정)

📙 작업 내역

  • 디자인 QA 수정사항 반영
  • 자세한 사항은 피그마에

🧪 테스트 내역

  • 브라우저/기기에서 동작 확인
  • 엣지 케이스 테스트 완료
  • 기존 기능 영향 없음

Summary by CodeRabbit

  • New Features

    • 타입 기반 스타일과 단어 하이라이트를 지원하는 새 라벨(BKLabel2) 추가
    • 다이얼로그 부제목을 선택적(optional)으로 표시
    • 텍스트필드 클리어 버튼 모드 설정 API 추가 및 검색결과에 따라 자동 전환
    • 도서 요약 뷰에 Big 스타일 추가
    • 최근 키워드 탭 시 검색창에 텍스트 자동 입력
  • UI/Style

    • 버튼 기본 크기(대) 적용, 폰트·간격·여백·아이콘 위치 다수 조정
    • 텍스트뷰 테두리 기본 숨김 → 오류 시만 표시
    • 문구·표기 소소 변경(“페이지 순”, “P”), 홈 빈 상태 문구·이미지 크기 수정
  • Chores

    • 프로비저닝 프로필 변경 및 앱 버전 1.0.1 업데이트

@coderabbitai
Copy link

coderabbitai bot commented Aug 19, 2025

Walkthrough

여러 UI 컴포넌트에서 레이블 시스템을 정비(BKLabel 적용 경로 변경·신규 BKLabel2 추가 및 다수 마이그레이션), 텍스트필드 클리어버튼/스타일 확장, 다이얼로그 부제목을 옵셔널로 변경했으며 버튼 생성 API에 사이즈 인자가 도입되고 다수 화면의 레이아웃·카피·스페이싱이 조정되었습니다. 빌드 프로비저닝 프로필도 변경되었습니다.

Changes

Cohort / File(s) Summary
타이포그래피·라벨 코어
.../Typography/BKTextStyle.swift, .../Label/BKLabel.swift, .../Label/BKLabel2.swift
BKTextStyle에 mutableAttributedString 추가. BKLabel의 공개 경로에서 applyRecommended()로 교체. 신규 공용 컴포넌트 BKLabel2 추가(타입 기반 스타일, 하이라이트 API, 불필요한 UILabel 프로퍼티 사용 비권장).
레이블 마이그레이션(컴포넌트/뷰)
.../Chip/BKChip.swift, .../TextField/BKTextFieldView.swift, .../MainFlow/BookDetail/View/BookDetailViewCell.swift, .../BookDetail/View/BookDetailViewHeader.swift, .../BookDetail/View/SeedReportView.swift, .../Home/View/RecordCountView.swift
여러 뷰/컴포넌트에서 BKLabel → BKLabel2로 교체. 폰트·색상 매핑 및 하이라이트 설정 적용. SeedReportView는 케이스 순서 변경, 레이아웃·배경 조정 포함.
바텀시트 타이틀 정리
.../BottomSheet/BKBottomSheetTitleView.swift
타이틀/서브타이틀을 BKLabel API로 통일하고 서브타이틀은 존재 시에만 스택에 추가. 스페이싱 상수 통합(contentSpacing) 및 관련 레이아웃 조정.
다이얼로그 부제목 옵셔널화
.../Dialog/BKDialog.swift, .../Setting/View/SettingViewController.swift
BKDialog init의 subtitle을 optional로 변경하고 subtitle이 없을 때 레이블 숨김/미추가 처리. 호출부에서 빈 문자열 인자 제거. 버튼 영역 인셋 조정.
버튼 API 사이즈 인자 도입 및 사용처 수정
.../Button/BKButton.swift (서명 변경), .../Button/BKButtonGroup.swift, .../Search/View/BookRegistrationStatusView.swift
BKButton.primary/secondary 서명에 size 인자 추가. 사용처에서 .large 명시하여 버튼 생성. 동작은 동일하나 시각 크기 지정이 명시적으로 적용됨.
텍스트필드·텍스트뷰 개선 및 검색바 동작
.../TextField/BKBaseTextField.swift, .../TextField/BKTextView.swift, .../Search/View/SearchView.swift
BKBaseTextField에 setClearButtonMode 공개 API 추가 및 clear button 전용 rightView 구성(보임/숨김 로직 포함). 초기 보더/배경 정책 변경(.normal은 보더 제거). BKTextView는 기본 보더 제거하고 에러 시에만 보더 표시. SearchView는 검색 상태에 따라 clearButtonMode 토글 및 setSearchBarText API 추가.
북 디테일 뷰 레이아웃/문구
.../BookDetail/View/BookDetailView.swift, .../BookDetail/View/BookDetailViewHeader.swift, .../Common/Extension/BKBottomSheetViewController+.swift
정렬 라벨 문구 변경("페이지 순"). seedReportView와 divider의 제약 우선순위로 빈 상태 시 접기/펼치기 구현. 정렬시트 레이아웃을 스택에서 개별 제약으로 변경 및 옵션 인셋 조정.
서머리 뷰 스타일 추가
.../Summary/BKBookSummaryView.swift
BKBookSummaryViewStyle에 .big 추가 — 라벨 스타일 재지정, descriptionBlock 추가 및 extraLabel 조건부 배치.
스페이싱 상수 추가
.../GraphicSystem/BKSpacing.swift
spacing9(36) 추가.
이미지 오프셋 유틸 추가 및 백 아이콘 조정
.../Extension/UINavigationController+.swift
UIImage 확장(imageWithCustomRect, imageWithOffset) 추가. 백 버튼 이미지에 오프셋 적용.
프레젠테이션·레이아웃·카피 소규모 변경
.../ArchiveFlow/View/ArchiveView.swift, .../Home/View/HomeEmptyView.swift, .../Home/View/HomeView.swift, .../Note/View/AppreciationGuideButton.swift, .../Note/View/EmotionRegistrationView.swift, .../OnboardingFlow/View/OnboardingView.swift, .../Setting/View/SettingCell.swift
마진/스페이싱/인셋 조정, 이미지 사이즈 명시, 사용자 문구 변경, 하이라이트 색상(HEX) 변경, 일부 레이아웃 상수 제거/값 조정.
프레젠테이션 로직·인증·로그인 뷰
src/Projects/BKPresentation/Sources/AppCoordinator.swift, .../AuthFlow/View/LoginViewController.swift
인증 플로우를 fullScreen 모달로 표시 및 interactive dismissal 금지. LoginViewController에 닫기(X) 버튼 추가 및 navigationBar 가시성 제어 삭제.
상태·뷰모델 사소 조정
.../MainFlow/Setting/ViewModel/SettingViewModel.swift
accessMode 변경 시 isLoginRequired를 false로 설정하던 할당 삭제(로그인 요구 플래그 유지).
프로젝트 설정 및 버전
src/Projects/Booket/Project.swift, src/SupportingFiles/Booket/Info.plist
Release 타겟 프로비저닝을 Development로 변경. CFBundleShortVersionString 1.0 → 1.0.1.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as 사용자
  participant SV as SearchView
  participant TF as BKSearchTextField(BKBaseTextField)
  Note over SV,TF: 상태 적용(.result)
  SV->>SV: applySnapshot(state)
  alt 결과 책 0개
    SV->>TF: setClearButtonMode(.whileEditing)
  else 결과 책 존재
    SV->>TF: setClearButtonMode(.always)
  end
  Note over User,SV: 최근 검색어 탭
  User->>SV: didTapRecent(keyword)
  SV->>SV: setSearchBarText(with: keyword)
  SV-->>TF: 내부적으로 text 업데이트
Loading
sequenceDiagram
  autonumber
  participant VC as Caller
  participant D as BKDialog
  participant TS as titleStack
  VC->>D: init(title, subtitle: String?)
  D->>D: setup()
  D->>TS: addArrangedSubview(titleLabel)
  alt subtitle != nil && subtitle != ""
    D->>TS: addArrangedSubview(subtitleLabel)
    D->>D: subtitleLabel.isHidden = false
  else
    D->>D: subtitleLabel.isHidden = true
  end
Loading
sequenceDiagram
  autonumber
  participant BD as BookDetailView
  participant SR as seedReportView
  participant DV as divider
  BD->>BD: applySnapshot(items)
  alt items.isEmpty
    BD->>SR: isHidden = true
    BD->>BD: seedReportZeroHeight.priority = required
    BD->>DV: dividerTopToButtons.priority = high
  else
    BD->>SR: isHidden = false
    BD->>BD: seedReportZeroHeight.priority = low
    BD->>DV: dividerTopToSeed.priority = high
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BOOK-268-fix/#175

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or @coderabbitai 요약 to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot requested a review from doyeonk429 August 19, 2025 19:29
@doyeonk429 doyeonk429 added the 🐞 fix Something isn't working label Aug 19, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/Projects/BKDesign/Sources/Components/TextField/BKTextFieldView.swift (1)

15-19: isError 토글 시 helpMessageLabel 색상 미갱신 버그

isErrordidSet에서 텍스트필드 타입만 바꾸고, helpMessageLabel 색상은 갱신하지 않습니다. 현재 handleError()가 해당 색상 반영을 담당하지만 초기 setup()에서만 호출되어, 이후 setHelpMessage(_, isError:)로 에러 상태를 바꿔도 라벨 색상이 업데이트되지 않을 수 있습니다.

다음과 같이 didSet에서 handleError()를 호출하도록 수정해 주세요:

 private var isError: Bool = false {
     didSet {
-        isError ? textField.setType(type: .error) : textField.setType(type: .normal)
+        handleError()
     }
 }
src/Projects/BKPresentation/Sources/Common/Extension/UINavigationController+.swift (1)

268-275: 강제 언래핑으로 인한 크래시 위험 제거

imageWithOffset의 반환값을 강제 언래핑(!)하고 있어 드물게 nil 발생 시 크래시 위험이 있습니다. 안전한 디폴트(원본 이미지)로 폴백하도록 수정하세요.

-        let backImage = BKImage.Icon.chevronLeft
-            .withRenderingMode(.alwaysTemplate)
-            .imageWithOffset(x: -4, y: 2)!
-            .withAlignmentRectInsets(
-                UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0)
-            )
+        let baseChevron = BKImage.Icon.chevronLeft
+            .withRenderingMode(.alwaysTemplate)
+        let offsetChevron = baseChevron.imageWithOffset(x: -4, y: 2) ?? baseChevron
+        let backImage = offsetChevron.withAlignmentRectInsets(
+            UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0)
+        )
src/Projects/BKDesign/Sources/Components/TextField/BKBaseTextField.swift (1)

146-160: clear 버튼 rightView 크기 미설정으로 표시되지 않을 수 있음

rightView는 Auto Layout이 아닌 뷰의 frame에 의존합니다. 현재 컨테이너 뷰 크기를 지정하지 않아 clear 버튼이 보이지 않거나 영역이 0으로 계산될 가능성이 큽니다. 초기 hidden 상태도 설정하는 것이 안전합니다.

     func applyClearButtonStyle() {
-        let containerView = UIView()
-        containerView.addSubview(clearButton)
-        addTarget(self, action: #selector(updateClearButtonVisibility), for: .editingChanged)
-        clearButton.addTarget(self, action: #selector(clearButtonTapped), for: .touchUpInside)
-        rightView = containerView
-        rightViewMode = .whileEditing
+        let containerView = UIView()
+        // UITextField는 rightView의 오토레이아웃을 사용하지 않으므로 명시적 크기가 필요합니다.
+        containerView.frame = CGRect(
+            x: 0, y: 0,
+            width: LayoutConstants.textRightInset,
+            height: LayoutConstants.height
+        )
+        containerView.addSubview(clearButton)
+        addTarget(self, action: #selector(updateClearButtonVisibility), for: .editingChanged)
+        addTarget(self, action: #selector(updateClearButtonVisibility), for: .editingDidBegin)
+        clearButton.addTarget(self, action: #selector(clearButtonTapped), for: .touchUpInside)
+        rightView = containerView
+        rightViewMode = .whileEditing
+        // 초기 상태 반영
+        clearButton.isHidden = (text?.isEmpty ?? true)
         
         clearButton.snp.makeConstraints {
             $0.height.width.equalTo(LayoutConstants.clearButtonSize)
             $0.top.leading.bottom.equalToSuperview()
             $0.trailing.equalToSuperview()
                 .inset(LayoutConstants.horizontalInset)
         }
     }
src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift (1)

75-80: BKButton(size:) 필수화 사항 반영 필요

addNoteButton에서 기본 생성자(BKButton())를 사용 중입니다. PR 요약대로 BKButton 생성자가 stylesize 인자를 요구하도록 변경되었으므로, 컴파일 타임 오류는 아니지만 디자인 일관성과 향후 유지보수를 위해 아래와 같이 명시적 인자 전달로 교체해주세요.

수정 예시 (디자인 스펙에 맞게 style/size 값 조정):

-    private let addNoteButton: BKButton = {
-        let button = BKButton()
+    private let addNoteButton: BKButton = {
+        let button = BKButton(style: .primary, size: .medium)
         button.title = "독서 기록 추가"
         
         button.setContentHuggingPriority(.defaultLow, for: .horizontal)
         return button
     }()

검토된 사용처:

  • SentenceRegistrationView: 이미 style/size 전달 중
  • LoginView: 이미 style/size(또는 custom) 전달 중
  • SentenceAppreciationView: 이미 style/size 전달 중

BookDetailView에도 동일한 패턴을 적용해 주세요.

🧹 Nitpick comments (32)
src/Projects/BKPresentation/Sources/MainFlow/Setting/View/SettingCell.swift (1)

41-41: Subviews는 contentView에 추가하는 것이 안전합니다

현재 셀(self)에 직접 addSubview 하고 있어 selection/highlight 배경, layoutMargins 처리에서 미묘한 차이가 생길 수 있습니다. 영향이 없으면 유지해도 되지만, 일반적인 UICollectionViewCell 관례와 재사용 안정성을 위해 contentView에 추가하는 것을 권장합니다.

예시:

[titleLabel, iconView, versionLabel].forEach { contentView.addSubview($0) }
src/Projects/BKDesign/Sources/Components/Button/BKButtonGroup.swift (2)

100-104: horizontal 레이아웃 분배 전략 재검토 제안 (.fillProportionally 권장)

과거 팀 합의(학습 메모)에 따르면 horizontal에서는 콘텐츠 길이에 비례한 너비(.fillProportionally)를 선호했습니다. 현재는 .fillEqually여서 긴 텍스트 버튼이 잘리는 케이스가 생길 수 있습니다. 스코프 외 변경이지만, 다음과 같이 바꾸는 것을 권장합니다.

원하시면 PR 분리해 반영 패치 제안 드리겠습니다.

예시:

  • .horizontal: stackView.distribution = .fillProportionally
  • .fullWidth: 현행대로 .fillEqually 유지(두 버튼 균등 너비 의도)

211-214: threeButtonGroup의 secondary/primary에도 사이즈 명시로 일관성 유지 제안

twoButtonGroup/singleFullButton는 .large를 명시하지만, threeButtonGroup은 기본값(아마 .medium)에 의존합니다. 동일 화면군에서 버튼 크기가 섞여 보일 수 있으므로, center/right에도 size를 명시하는 것을 권장합니다.

예시(참고용):

let centerButton = BKButton.secondary(title: centerTitle, size: .large)
let rightButton = BKButton.primary(title: rightTitle, size: .large)
src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeView.swift (1)

149-151: 매직 넘버(2) 대신 레이아웃 상수 사용으로 일관성 확보 권장

컬렉션뷰 상단 오프셋을 하드코딩된 2가 아니라 LayoutConstants.collectionTopSpacing을 사용하도록 변경하면, 상수 한 곳으로 디자인 스펙을 관리할 수 있어 유지보수성과 일관성이 좋아집니다. 또한 empty 상태(homeEmptyView)와 non-empty 상태 간 상단 간격이 상수 기반으로 동기화되어 UI 불일치 위험을 줄일 수 있습니다.

아래와 같이 수정 제안드립니다:

-            $0.top
-                .equalTo(bookSectionTitleLabel.snp.bottom)
-                .offset(2)
+            $0.top
+                .equalTo(bookSectionTitleLabel.snp.bottom)
+                .offset(LayoutConstants.collectionTopSpacing)

추가 확인 사항:

  • 현재 homeEmptyViewbookSectionTitleLabel.snp.bottom에 offset 없이 붙고(라인 156-160), 높이에서만 collectionTopSpacing을 더하고 있습니다. 실제 의도가 타이틀과 콘텐츠 사이 간격의 시각적 일치라면, empty 상태에서도 top에 동일한 offset을 주는 것이 자연스럽습니다. 디자이너 스펙에 맞게 아래와 같이 검토해 주세요(예시):
homeEmptyView.snp.makeConstraints {
    $0.top.equalTo(bookSectionTitleLabel.snp.bottom)
        .offset(LayoutConstants.collectionTopSpacing) // 필요 시 추가
    $0.leading.trailing.equalToSuperview()
    $0.height.equalTo(LayoutConstants.collectionHeight + LayoutConstants.collectionTopSpacing)
}

검증 제안:

  • 책 목록이 비어있는 상태/비어있지 않은 상태 모두에서, 타이틀-콘텐츠 상단 간격이 동일하게 보이는지 스냅샷 혹은 시뮬레이터로 확인 부탁드립니다.
src/Projects/BKPresentation/Sources/MainFlow/Note/View/EmotionRegistrationView.swift (1)

199-200: spacing 매직 넘버(24) → 디자인 토큰 사용 검토

간격을 40→24로 줄인 의도 자체는 이해됩니다. 다만, 다른 곳에서 BKSpacing/BKInset 토큰을 쓰는 패턴과 일관되게 24도 토큰으로 표현 가능하면 교체를 권장합니다(예: BKSpacing.spacingX 또는 BKInset.insetY).

추가 확인:

  • 디자이너 스펙에서 정확히 24pt가 지정된 값인지, 혹은 가장 가까운 토큰으로 스냅이 의도인지 확인해 주세요. 다양한 화면 크기에서 시각 균형이 유지되는지도 함께 검증 부탁드립니다.
src/Projects/BKDesign/Sources/Foundation/Typography/BKTextStyle.swift (1)

345-365: 중복 제거: mutableAttributedString는 기존 attributedString 결과를 재사용하세요

동일한 속성 구성 로직이 중복됩니다. 유지보수성과 일관성을 위해 attributedString을 호출해 생성한 결과를 NSMutableAttributedString으로 감싸는 방식으로 단순화하는 것을 권장합니다.

-    public func mutableAttributedString(
-        from text: String,
-        color: UIColor = .label,
-        extraAttributes: [NSAttributedString.Key: Any] = [:]
-    ) -> NSMutableAttributedString {
-        var attributes: [NSAttributedString.Key: Any] = [
-            .font: uiFont ?? UIFont.systemFont(ofSize: fontAttributes.fontSize.rawValue),
-            .foregroundColor: color,
-            .paragraphStyle: paragraphStyle
-        ]
-        
-        if let letterSpacing = fontAttributes.letterSpacing {
-            let actualLetterSpacing = letterSpacing.calculateAbsoluteLetterSpacing(
-                for: fontAttributes.fontSize.rawValue
-            )
-            attributes[.kern] = actualLetterSpacing
-        }
-        
-        attributes.merge(extraAttributes) { $1 }
-        return NSMutableAttributedString(string: text, attributes: attributes)
-    }
+    public func mutableAttributedString(
+        from text: String,
+        color: UIColor = .label,
+        extraAttributes: [NSAttributedString.Key: Any] = [:]
+    ) -> NSMutableAttributedString {
+        return NSMutableAttributedString(
+            attributedString: attributedString(from: text, color: color, extraAttributes: extraAttributes)
+        )
+    }
src/Projects/BKPresentation/Sources/Common/Extension/UINavigationController+.swift (1)

342-351: 렌더 실패 시 안전 폴백 반환

UIGraphicsGetImageFromCurrentImageContext()가 nil일 가능성(메모리 부족/컨텍스트 실패 등)을 고려해 자기 자신으로 폴백하세요. 현재 시그니처(UIImage?)를 유지하면서도 사실상 nil을 반환하지 않게 만들 수 있습니다.

-    func imageWithCustomRect(_ rect: CGRect, canvasSize: CGSize? = nil) -> UIImage? {
+    func imageWithCustomRect(_ rect: CGRect, canvasSize: CGSize? = nil) -> UIImage? {
         let finalCanvasSize = canvasSize ?? size
         
         UIGraphicsBeginImageContextWithOptions(finalCanvasSize, false, scale)
         defer { UIGraphicsEndImageContext() }
         
         draw(in: rect)
         
-        return UIGraphicsGetImageFromCurrentImageContext()?.withRenderingMode(renderingMode)
+        return UIGraphicsGetImageFromCurrentImageContext()?.withRenderingMode(renderingMode) ?? self
     }
src/Projects/BKDesign/Sources/Components/TextField/BKBaseTextField.swift (2)

129-135: 타입 변경 시 borderWidth도 함께 갱신 필요

초기 구성에서는 .normal일 때 borderWidth = 0으로 설정하지만, 이후 setType으로 타입을 바꿀 때는 typeDidChanged()borderColor만 갱신합니다. 이로 인해 .normal로 되돌렸을 때도 border가 남는 불일치가 발생합니다.

다음과 같이 typeDidChanged()를 수정하는 것을 제안합니다(선택 적용):

// 파일 내 기존 메서드 교체 제안 (참고용)
func typeDidChanged() {
    switch textFieldType {
    case .normal:
        layer.borderWidth = 0
        layer.borderColor = textFieldType.borderColor.cgColor
    default:
        layer.borderWidth = LayoutConstants.borderWidth
        layer.borderColor = textFieldType.borderColor.cgColor
    }
}

104-106: rightViewMode 중복 설정 가능성

초기 configure()applyClearButtonStyle()에서 항상 .whileEditing으로 덮습니다. 외부에서 setClearButtonMode(_) 를 사용하는 경우, 호출 순서에 따라 설정이 덮일 수 있습니다. 문서화하거나 applyClearButtonStyle()에서 기존 rightViewMode를 유지하도록 조정하는 것을 고려하세요.

src/Projects/BKDesign/Sources/Components/Dialog/BKDialog.swift (2)

108-119: 빈 문자열 subtitle은 스택에 추가하지 않는 편이 일관적입니다

setup()에서는 subtitleText != nil만 검사하여 빈 문자열도 스택에 추가될 수 있습니다. configure()에서는 빈 문자열이면 hidden 처리하므로 스택 구조와 표시 로직이 엇갈립니다. 초기부터 비어있는 경우 추가하지 않도록 하는 것이 깔끔합니다.

-        // subtitle이 있을 때만 추가
-        if subtitleText != nil {
+        // subtitle이 유효할 때만 추가
+        if let subtitle = subtitleText?.trimmingCharacters(in: .whitespacesAndNewlines),
+           !subtitle.isEmpty {
             titleStack.addArrangedSubview(subtitleLabel)
         }

145-151: 매직 넘버(4) 대신 상수 사용

LayoutConstants.buttonBottomInset가 선언되어 있으나 사용되지 않았습니다. 일관성을 위해 상수로 교체하세요.

         buttonGroup.snp.makeConstraints {
             $0.top.equalTo(rootStack.snp.bottom)
                 .offset(LayoutConstants.buttonTopInset)
             $0.leading.trailing.equalToSuperview()
             $0.height.equalTo(84)
-            $0.bottom.equalToSuperview().inset(4)
+            $0.bottom.equalToSuperview().inset(LayoutConstants.buttonBottomInset)
         }
src/Projects/BKDesign/Sources/Components/Label/BKLabel2.swift (3)

31-35: 오류 메시지 수정: setFont가 아니라 setFontStyle입니다

사용자 가이던스 메시지가 실제 제공 API와 다릅니다. 혼선을 줄이기 위해 메시지를 setFontStyle(_:)로 수정하세요.

-    @available(*, unavailable, message: "Implement `setFont(_:)` instead.")
+    @available(*, unavailable, message: "Use `setFontStyle(_:)` instead.")
     override public var font: UIFont! {
         get { super.font }
         set { super.font = newValue }
     }

133-141: 여러 하이라이트 발생 및 대소문자 옵션 지원 제안

현재는 첫 번째 일치만, 대소문자 구분으로 하이라이트합니다. UX 요구에 따라 전체 일치/대소문자 무시 옵션을 지원할 수 있습니다.

예시(전체 일치, 대소문자 무시):

let lcText = labelText.lowercased()
let lcWord = word.lowercased()
var searchRange = lcText.startIndex..<lcText.endIndex
while let foundRange = lcText.range(of: lcWord, options: [], range: searchRange) {
    let nsRange = NSRange(foundRange, in: lcText)
    attributedString.addAttribute(.foregroundColor, value: highlightColor, range: nsRange)
    if let highlightFont = highlightFont {
        attributedString.addAttribute(.font, value: highlightFont, range: nsRange)
    }
    searchRange = foundRange.upperBound..<lcText.endIndex
}

76-89: 기본 정렬값 재검토 제안

기본 정렬을 .justified로 두면 짧은 텍스트에서도 어색한 간격이 생길 수 있습니다. 일반 라벨의 기본은 .natural 또는 .left가 더 무난합니다.

src/Projects/BKPresentation/Sources/MainFlow/Note/View/AppreciationGuideButton.swift (1)

28-32: 하드코딩된 Hex 컬러 사용은 다크 모드/디자인 토큰 일관성에 취약합니다

placeholder 하이라이트 컬러를 UIColor(hex: "D6D6D6")로 고정하면 라이트/다크 테마 전환 시 대비 불일치가 발생할 수 있고, 디자인 시스템 토큰 흐름(.bkContentColor 등)에서 이탈합니다. 명시적으로 토큰을 쓰거나(예: .bkContentColor(.disable) 혹은 유사한 토큰), 이번 스펙이 정확한 0xD6D6D6를 요구한다면 BKDesign 내 팔레트/토큰으로 승격해 관리하는 편이 안전합니다.

적용 예(토큰 회귀):

-        highlightColor: UIColor(hex: "D6D6D6")
+        highlightColor: .bkContentColor(.disable)

토큰이 정확히 맞지 않는다면 BKDesign 팔레트에 신규 토큰(예: neutral200) 정의 후 사용을 권장합니다.

src/Projects/BKDesign/Sources/Components/Chip/BKChip.swift (1)

6-7: BKLabel2 마이그레이션 LGTM + 라벨 단일 라인 고정 권장

BKLabel2로의 전환은 API 호환(setText/setFontStyle/setColor) 측면에서 문제 없어 보입니다. 다만 칩 내부 라벨이 길어지는 경우 줄바꿈으로 칩 높이/레이아웃이 틀어질 수 있으니 단일 라인 고정을 고려해 주세요.

추가 제안:

     private func setupViews() {
-        titleLabel.setText(text: title)
-        countLabel.setText(text: "\(count)")
+        titleLabel.setText(text: title)
+        titleLabel.numberOfLines = 1
+        countLabel.setText(text: "\(count)")
+        countLabel.numberOfLines = 1
         countLabel.setFontStyle(style: .label1(weight: .semiBold))
src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchSectionHeaderView.swift (1)

67-74: 기본 텍스트 색상을 디자인 토큰으로 교체 권장 (다크 모드/일관성)

base 색상을 .black로 고정하면 테마/다크 모드 일관성이 깨질 수 있습니다. 디자인 시스템 토큰 사용을 권장합니다.

적용 diff:

-            attributes: [
-                .font: baseFont,
-                .foregroundColor: UIColor.black
-            ]
+            attributes: [
+                .font: baseFont,
+                .foregroundColor: UIColor.bkContentColor(.primary)
+            ]

추가 제안(참고): .recent 분기(라인 42)의 폰트 스타일도 본 변경 의도에 맞춰 .label1(weight: .medium)으로 통일하는 방안 검토 부탁드립니다.

src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift (3)

22-31: 일관성 측면에서 noteLabel도 BKLabel2로 전환 고려

동일 셀 내 라벨 타입 혼재는 추후 유지보수/테마 일관성에 불리합니다. 영향 범위가 작으면 noteLabel도 BKLabel2로 이관을 검토해 주세요.


79-83: emotion 아이콘 크롭 가능성 — 의도 확인 및 대안 제시

.scaleAspectFill + cornerRadius + clipsToBounds 조합은 비정사각 이미지에서 크롭이 발생합니다. 배경색도 지정되어 있어 아이콘/심볼 형태에 따라 상자처럼 보일 수 있습니다. 크롭이 의도되지 않았다면 아래 대안을 고려해 주세요.

대안 예시:

-        emotionIcon.contentMode = .scaleAspectFill
+        emotionIcon.contentMode = .scaleAspectFit
         emotionIcon.layer.cornerRadius = LayoutConstants.imageCornerRadius
         emotionIcon.clipsToBounds = true
-        emotionIcon.backgroundColor = .bkBaseColor(.primary)
+        // 필요 시 배경 제거 또는 반투명 토큰 사용
+        // emotionIcon.backgroundColor = .clear

85-85: 페이지 표기 'P' 대문자 — 용어 표기 일관성 확인

다른 화면/리스트에서 소문자 p 또는 한글 “쪽”을 사용한다면 통일이 필요할 수 있습니다. 디자인/카피 가이드와 일치하는지 확인해 주세요.

src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchView.swift (2)

103-114: 결과 유무에 따른 clear 버튼 모드 전환 OK — ‘최근’ 상태에서의 초기화도 추가 권장

.result 상태에서 빈/존재 케이스별로 .whileEditing / .always 전환은 합리적입니다. 다만 .recent 상태로 전환될 때 명시적으로 모드를 초기화하지 않으면 이전 상태의 모드가 잔존할 수 있습니다. .recent 분기에서도 기본값(.whileEditing 등)을 명시해 주는 게 안정적입니다.

아래처럼 .recent 분기에 초기화 한 줄 추가하는 것을 고려해 주세요(선택 사항, 변경 위치는 현 변경 범위 밖이므로 참고용 코드입니다):

case .recent(let state):
    // ... 스냅샷 구성 로직
    searchBar.setClearButtonMode(.whileEditing)

166-168: 최근 검색어 탭 시 이벤트/텍스트 설정 순서 미세 조정 제안

UX 관점에서 사용자가 탭하자마자 검색바에 텍스트가 먼저 반영되고, 이어서 검색 이벤트가 전달되는 편이 자연스럽습니다. 기능엔 영향 없으나 순서만 바꿔두면 미세한 깜빡임을 줄일 수 있습니다.

-            self?.eventPublisher.send(.search(keyword))
-            self?.setSearchBarText(with: keyword)
+            self?.setSearchBarText(with: keyword)
+            self?.eventPublisher.send(.search(keyword))
src/Projects/BKPresentation/Sources/Common/Extension/BKBottomSheetViewController+.swift (1)

32-35: divider에 음수 inset 사용은 오버플로우/시각적 절단 리스크

equalToSuperview().inset(-BKSpacing.spacing5)는 슈퍼뷰 폭을 넘어 확장합니다. 의도(풀블리드 라인)라면 안전하지만, 컨테이너/시트 가장자리와 겹치거나 클리핑될 수 있습니다. 오버플로우를 피하려면 음수 inset 대신 슈퍼뷰와 동일 폭으로 두는 게 안전합니다.

-            $0.leading.trailing.equalToSuperview().inset(-BKSpacing.spacing5)
+            $0.leading.trailing.equalToSuperview()

의도가 “좌우 여백 무시하고 풀블리드”라면, 시트 내부 컨텐츠 패딩을 조정하거나 divider 자체의 내부 레이아웃 가이드를 활용하는 대안을 고려해 주세요.

src/Projects/BKDesign/Sources/Components/Label/BKLabel.swift (1)

31-35: 오류 메시지 문구 수정 제안

개발자 가이던스 정확성을 위해 ‘Implement setFont(_:)’ 대신 실제 API 이름을 안내하는 것이 좋습니다.

참고(수정 제안 코드 — 변경 범위 밖):

@available(*, unavailable, message: "Use `setFontStyle(style:)` instead.")
override public var font: UIFont! { ... }
src/Projects/BKDesign/Sources/Components/BottomSheet/BKBottomSheetTitleView.swift (1)

75-96: leading 스타일의 텍스트 정렬을 .left로 고정 권장

BKLabel 기본 정렬(.justified)은 다행히 단일 행에서 문제 없지만, 두 줄 이상에서 불필요한 양끝맞춤이 발생할 수 있습니다. leading 레이아웃에서는 .left가 더 예측 가능하고 자연스럽습니다.

참고(변경 범위 밖, 예시 코드):

// configure() 내에서 스타일별 정렬 명시
switch style {
case .leadingCloseButton:
    titleLabel.textAlignment = .left
    subtitleLabel.textAlignment = .left
case .centered:
    titleLabel.textAlignment = .center
    subtitleLabel.textAlignment = .center
}
src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift (1)

119-125: reportContainer 높이 고정(42) — 텍스트 길이/다국어 대응 시 클리핑 가능성

요약 문구가 길어질 경우(탑 감정 복수, 소형 단말, 다국어) 42pt 고정은 줄바꿈/말줄임 처리가 필요합니다. 두 가지 중 하나를 권장합니다.

옵션 A: 한 줄 고정 + 말줄임 처리

  • configure() 등에서 설정 추가(참고 코드, 변경 범위 밖):
reportLabel.numberOfLines = 1
reportLabel.lineBreakMode = .byTruncatingTail

옵션 B: 동적 높이 허용

-            $0.height.equalTo(42)
+            // 동적 높이: 고정값 제거

의도된 고정 높이라면(디자인 고정값), A를 적용해 클리핑만 방지해 주세요.

src/Projects/BKDesign/Sources/Components/Summary/BKBookSummaryView.swift (3)

137-157: big 스타일 추가 전반적으로 👍; 중복 로직 정리 및 재사용성 개선 제안

  • 폰트 계층과 descriptionBlock 구성은 의도대로 보입니다. BKLabel.setFontStyle가 내부에서 applyRecommended를 호출하므로 반영도 문제 없습니다.
  • 다만 descriptionStack/descriptionBlock 구성(서브뷰 추가, extraLabel 조건부 추가)이 default 분기와 상당히 중복됩니다. 유지보수/QA 대응을 위해 공통 헬퍼로 추출을 권장합니다.

아래와 같이 공통 헬퍼를 도입해 switch 각 분기에서 재사용하면 중복을 줄일 수 있습니다.

@@
-        case .big:
-            titleLabel.setFontStyle(style: .headline1(weight: .semiBold))
-            authorLabel.setFontStyle(style: .label2(weight: .regular))
-            separatorLabel.setFontStyle(style: .label2(weight: .regular))
-            publisherLabel.setFontStyle(style: .label2(weight: .regular))
-            extraLabel.setFontStyle(style: .label2(weight: .regular))
-
-            let descriptionBlock = UIStackView(arrangedSubviews: [descriptionStack])
-            descriptionBlock.axis = .vertical
-            descriptionBlock.alignment = .leading
-            descriptionBlock.spacing = 0
-
-            descriptionStack.addArrangedSubview(authorLabel)
-            descriptionStack.addArrangedSubview(separatorLabel)
-            descriptionStack.addArrangedSubview(publisherLabel)
-            labelStack.addArrangedSubview(descriptionBlock)
-
-            if style.showsExtraLabel {
-                descriptionBlock.addArrangedSubview(extraLabel)
-                descriptionBlock.setCustomSpacing(style.extraLabelTopOffset, after: descriptionStack)
-            }
+        case .big:
+            applyBigFonts()
+            buildDescriptionBlock(addExtra: style.showsExtraLabel, extraTop: style.extraLabelTopOffset)

그리고 파일 내(선택된 범위 외) 헬퍼를 추가:

private func buildDescriptionBlock(addExtra: Bool, extraTop: CGFloat) {
    let descriptionBlock = UIStackView(arrangedSubviews: [descriptionStack])
    descriptionBlock.axis = .vertical
    descriptionBlock.alignment = .leading
    descriptionBlock.spacing = 0

    descriptionStack.addArrangedSubview(authorLabel)
    descriptionStack.addArrangedSubview(separatorLabel)
    descriptionStack.addArrangedSubview(publisherLabel)
    labelStack.addArrangedSubview(descriptionBlock)

    if addExtra {
        descriptionBlock.addArrangedSubview(extraLabel)
        descriptionBlock.setCustomSpacing(extraTop, after: descriptionStack)
    }
}

private func applyBigFonts() {
    titleLabel.setFontStyle(style: .headline1(weight: .semiBold))
    authorLabel.setFontStyle(style: .label2(weight: .regular))
    separatorLabel.setFontStyle(style: .label2(weight: .regular))
    publisherLabel.setFontStyle(style: .label2(weight: .regular))
    extraLabel.setFontStyle(style: .label2(weight: .regular))
}

269-276: alreadyEnroll 분기의 extraLabel 세팅 분기는 실질적으로 미실행(dead code)

alreadyEnroll 스타일에서는 showsExtraLabel이 항상 false라서, 이 분기의 extraLabel 설정은 실행되지 않습니다. 혼동을 줄이기 위해 제거 또는 코멘트 보강을 권장합니다.

아래와 같이 단순 제거 가능합니다:

         case .alreadyEnroll:
             thubmnailCoverView.clipsToBounds = true
             thubmnailCoverView.layer.cornerRadius = LayoutConstants.imageRadius
-            
-            if style.showsExtraLabel, let text = extraText {
-                extraLabel.setText(text: text)
-            }

48-48: 오타: thubmnailCoverView → thumbnailCoverView 네이밍 정리 제안

속성명이 반복해서 사용되므로 오타를 조기에 정리하는 편이 좋습니다. 리팩터 도중 오표기로 인한 참조 오류를 줄일 수 있습니다.

원하면 이 파일 내 사용처까지 포함한 리네이밍 패치를 제안드릴 수 있습니다.

src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift (3)

168-170: seedReportView의 zero-height 제약만으로 충분합니다

현재 height == 0(우선순위 토글)과 height ≥ 0 제약을 동시에 잡고 있는데, 후자는 실질적인 역할이 없습니다. 간소화를 위해 ≥ 0 제약과 그 레퍼런스 속성 제거를 권장합니다.

아래처럼 정리 가능합니다:

-    private var seedReportViewHeightConstraint: Constraint?
@@
-            seedReportZeroHeight = $0.height.equalTo(0).priority(.low).constraint
-            seedReportViewHeightConstraint = $0.height.greaterThanOrEqualTo(0).constraint
+            seedReportZeroHeight = $0.height.equalTo(0).priority(.low).constraint

222-228: empty 상태 전환 시 히든/우선순위 동기화 OK; 레이아웃 강제 갱신 고려

isHidden과 우선순위 토글이 일관되게 적용되어 있습니다. 전환 애니메이션이나 즉시 반영이 필요하다면 우선순위 업데이트 직후 containerView.layoutIfNeeded()를 호출하는 방식을 고려해 보세요.


384-385: summaryView 높이(98)와 .big 썸네일(높이 100) 불일치

.big 스타일에서 BKBookSummaryView의 썸네일 높이가 100인데, 현재 summaryView 고정 높이는 98입니다. superview 바깥으로 2pt가 넘칠 수 있고, 인접 섹션과 겹침 가능성이 있습니다. 최소 100으로 상향하거나 스타일별 높이로 분기하는 것을 권장합니다.

-        static let summaryViewHeight: CGFloat = 98
+        static let summaryViewHeight: CGFloat = 100

대안: 스타일 주입 시 높이를 외부에서 결정하거나(BKBookSummaryViewStyle.thumbnailSize.height 사용), 오토레이아웃으로 내재 콘텐츠에 맞춰 유연하게 잡는 방법도 있습니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d5e1ff0 and da6bbe1.

📒 Files selected for processing (32)
  • src/Projects/BKDesign/Sources/Components/BottomSheet/BKBottomSheetTitleView.swift (5 hunks)
  • src/Projects/BKDesign/Sources/Components/Button/BKButtonGroup.swift (2 hunks)
  • src/Projects/BKDesign/Sources/Components/Chip/BKChip.swift (1 hunks)
  • src/Projects/BKDesign/Sources/Components/Dialog/BKDialog.swift (4 hunks)
  • src/Projects/BKDesign/Sources/Components/Label/BKLabel.swift (5 hunks)
  • src/Projects/BKDesign/Sources/Components/Label/BKLabel2.swift (1 hunks)
  • src/Projects/BKDesign/Sources/Components/Summary/BKBookSummaryView.swift (2 hunks)
  • src/Projects/BKDesign/Sources/Components/TextField/BKBaseTextField.swift (2 hunks)
  • src/Projects/BKDesign/Sources/Components/TextField/BKTextFieldView.swift (3 hunks)
  • src/Projects/BKDesign/Sources/Components/TextField/BKTextView.swift (2 hunks)
  • src/Projects/BKDesign/Sources/Foundation/GraphicSystem/BKSpacing.swift (1 hunks)
  • src/Projects/BKDesign/Sources/Foundation/Typography/BKTextStyle.swift (2 hunks)
  • src/Projects/BKPresentation/Sources/ArchiveFlow/View/ArchiveView.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/Common/Extension/BKBottomSheetViewController+.swift (2 hunks)
  • src/Projects/BKPresentation/Sources/Common/Extension/UINavigationController+.swift (2 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift (4 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift (3 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewHeader.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift (4 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeEmptyView.swift (2 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeView.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Home/View/RecordCountView.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Note/View/AppreciationGuideButton.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Note/View/EmotionRegistrationView.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Search/View/BookRegistrationStatusView.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchSectionHeaderView.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchView.swift (4 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchViewController.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Setting/View/SettingCell.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Setting/View/SettingViewController.swift (0 hunks)
  • src/Projects/BKPresentation/Sources/OnboardingFlow/View/OnboardingView.swift (3 hunks)
  • src/Projects/Booket/Project.swift (1 hunks)
💤 Files with no reviewable changes (1)
  • src/Projects/BKPresentation/Sources/MainFlow/Setting/View/SettingViewController.swift
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-07-10T08:21:16.126Z
Learnt from: doyeonk429
PR: YAPP-Github/Reed-iOS#68
File: src/Projects/BKDesign/Sources/Components/Button/BKButtonGroup.swift:86-92
Timestamp: 2025-07-10T08:21:16.126Z
Learning: BKButtonGroup의 horizontal 레이아웃에서 stackView.distribution을 .fillProportionally로 설정한 것은 의도된 디자인입니다. doyeonk429는 버튼들이 콘텐츠 길이에 따라 다른 너비를 가지는 것을 선호합니다.

Applied to files:

  • src/Projects/BKDesign/Sources/Components/TextField/BKTextFieldView.swift
  • src/Projects/BKDesign/Sources/Components/Button/BKButtonGroup.swift
📚 Learning: 2025-07-14T05:23:04.937Z
Learnt from: clxxrlove
PR: YAPP-Github/Reed-iOS#80
File: src/Projects/BKDesign/Sources/Components/BottomSheet/BKBottomSheetViewController.swift:148-148
Timestamp: 2025-07-14T05:23:04.937Z
Learning: Reed-iOS 프로젝트의 BKBottomSheetViewController에서 버튼 영역 높이(84)는 디자인 시스템에 기반한 의도적인 고정값입니다. clxxrlove에 따르면 작은 기기에서도 동일한 크기가 유지되어야 하며, 동적 계산보다는 상수화만 필요합니다.

Applied to files:

  • src/Projects/BKDesign/Sources/Components/BottomSheet/BKBottomSheetTitleView.swift
  • src/Projects/BKDesign/Sources/Components/Dialog/BKDialog.swift
📚 Learning: 2025-08-11T12:49:16.942Z
Learnt from: doyeonk429
PR: YAPP-Github/Reed-iOS#169
File: src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchResultCell.swift:31-41
Timestamp: 2025-08-11T12:49:16.942Z
Learning: In Reed-iOS project's SearchResultCell, a new BKBookSummaryView instance is created each time configure() is called rather than reusing the existing view. The old view is properly removed and set to nil in prepareForReuse(), allowing deinitialization to handle all cleanup including image downloads. Calling clearView() before removal is unnecessary in this pattern.

Applied to files:

  • src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchView.swift
  • src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift
📚 Learning: 2025-07-08T17:15:59.793Z
Learnt from: doyeonk429
PR: YAPP-Github/Reed-iOS#63
File: src/Projects/BKDesign/Resources/Assets.xcassets/chevron-right.imageset/Contents.json:1-26
Timestamp: 2025-07-08T17:15:59.793Z
Learning: In the BKDesign project, all image assets referenced in Contents.json files are properly included in the repository with the correct 1x, 2x, and 3x variants. The chevron-right icon and other design system icons are complete and ready for use.

Applied to files:

  • src/Projects/BKPresentation/Sources/Common/Extension/UINavigationController+.swift
🧬 Code Graph Analysis (13)
src/Projects/BKDesign/Sources/Foundation/Typography/BKTextStyle.swift (1)
src/Projects/BKDesign/Sources/Foundation/Typography/BKFontMetrics.swift (1)
  • calculateAbsoluteLetterSpacing (51-53)
src/Projects/BKPresentation/Sources/Common/Extension/BKBottomSheetViewController+.swift (1)
src/Projects/BKDesign/Sources/Extensions/UIView+.swift (1)
  • addSubviews (7-9)
src/Projects/BKDesign/Sources/Components/TextField/BKTextView.swift (1)
src/Projects/BKDesign/Sources/Extensions/UIColor+.swift (2)
  • bkBaseColor (91-102)
  • bkBorderColor (65-76)
src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchViewController.swift (1)
src/Projects/BKDesign/Sources/Components/Button/BKButtonGroup.swift (1)
  • twoButtonGroup (165-185)
src/Projects/BKPresentation/Sources/MainFlow/Search/View/BookRegistrationStatusView.swift (1)
src/Projects/BKDesign/Sources/Components/Button/BKButton.swift (1)
  • secondary (351-358)
src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchView.swift (1)
src/Projects/BKDesign/Sources/Components/TextField/BKBaseTextField.swift (1)
  • setClearButtonMode (104-106)
src/Projects/BKDesign/Sources/Components/Summary/BKBookSummaryView.swift (1)
src/Projects/BKDesign/Sources/Components/Label/BKLabel.swift (1)
  • setFontStyle (103-107)
src/Projects/BKDesign/Sources/Components/Label/BKLabel.swift (1)
src/Projects/BKDesign/Sources/Foundation/Typography/BKTextStyle.swift (2)
  • attributedString (323-343)
  • mutableAttributedString (345-365)
src/Projects/BKDesign/Sources/Components/Button/BKButtonGroup.swift (1)
src/Projects/BKDesign/Sources/Components/Button/BKButton.swift (2)
  • secondary (351-358)
  • primary (342-349)
src/Projects/BKDesign/Sources/Components/TextField/BKBaseTextField.swift (1)
src/Projects/BKDesign/Sources/Extensions/UIColor+.swift (1)
  • bkBaseColor (91-102)
src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift (1)
src/Projects/BKDesign/Sources/Extensions/UIColor+.swift (1)
  • bkBaseColor (91-102)
src/Projects/BKDesign/Sources/Components/Label/BKLabel2.swift (2)
src/Projects/BKDesign/Sources/Extensions/UIColor+.swift (1)
  • bkContentColor (52-63)
src/Projects/BKDesign/Sources/Foundation/Typography/BKTextStyle.swift (1)
  • attributedString (323-343)
src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift (2)
src/Projects/BKDesign/Sources/Extensions/UIColor+.swift (2)
  • bkContentColor (52-63)
  • bkBaseColor (91-102)
src/Projects/BKPresentation/Sources/Common/Extension/Date+.swift (1)
  • toKoreanDotDateString (22-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (34)
src/Projects/BKPresentation/Sources/MainFlow/Setting/View/SettingCell.swift (2)

49-53: 아이콘 뷰 trailing 인셋 inset5로 조정 — 정합성 문제 없음

좌우 여백이 titleLabel의 leading(inset5)과 일관되게 맞춰졌습니다. 제약 간 충돌 소지도 없고, 디자인 토큰 기준에도 부합해 보입니다.


55-58: 버전 라벨 trailing 인셋 inset5로 조정 — 정합성 문제 없음

.chevron/.label 전환 시 isHidden 토글만 이뤄져 런타임 충돌 없이 동작하고, 좌우 여백도 통일되었습니다.

src/Projects/BKPresentation/Sources/MainFlow/Search/View/BookRegistrationStatusView.swift (1)

52-52: .large 사이즈 높이 일치 확인
.largeheight가 52로, 기존 LayoutConstants.buttonHeight(52)와 완전히 일치합니다. 오토레이아웃 제약 충돌 우려가 없으므로 그대로 머지해 주세요. LGTM.

src/Projects/BKDesign/Sources/Components/Button/BKButtonGroup.swift (2)

171-172: twoButtonGroup에 .large 사이즈 명시 — 시각적 일관성 향상

left=secondary(.large), right=primary(.large)로 명시해 fullWidth 레이아웃에서 버튼 높이·타이포 크기가 일관되게 맞춰집니다. group.primaryButton = rightButton과도 잘 호환됩니다.


240-240: 사소: 파일 말미 개행/서식 변경

기능 영향은 없습니다. 현재 상태 유지에 동의합니다.

src/Projects/BKPresentation/Sources/MainFlow/Home/View/RecordCountView.swift (1)

9-9: BKLabel2로의 전환 LGTM

BKLabel2로의 마이그레이션이 기존 사용 패턴(setText/setFontStyle/setColor + highlight 속성)과 호환되며, 본 뷰의 요구사항에 적절합니다.

src/Projects/BKDesign/Sources/Components/TextField/BKTextFieldView.swift (3)

7-7: 제목 레이블의 BKLabel2 전환 LGTM

BKLabel2 도입으로 타 컴포넌트와 라벨 시스템이 일관화되었습니다. 외부 API 변화 없이 내부만 갱신된 점도 좋습니다.


42-43: UIStackView 배치 전략 변경(.fill) 적절

세로 스택에서 .fill은 일반적인 선택이며, 콘텐츠 크기 우선 배치를 명확히 합니다. 현재 구성(제목-입력-헬프)의 의도에 부합합니다.


116-125: 세로 축 Hugging/Compression 우선순위 명시 좋습니다

세로 방향에서 각 구성요소의 레이아웃 안정성 확보에 도움 됩니다. 다만, 길이가 긴 도움말(여러 줄) 시 레이아웃이 충분히 확장되는지 한 번 확인해 주세요.

테스트 제안:

  • helpMessage를 2~3줄 이상으로 설정해 다양한 화면 높이(iPhone SE/Pro Max)에서 잘리는 현상이 없는지 점검 바랍니다.
src/Projects/BKDesign/Sources/Components/TextField/BKTextView.swift (1)

15-18: 기본 스타일(보더 숨김 + 베이스 배경) 갱신 LGTM

에러 시에만 보더를 노출하고 평상시에는 베이스 컬러 배경만 사용하는 방향이 디자인 시스템 변화와 잘 맞습니다.

src/Projects/BKDesign/Sources/Components/Dialog/BKDialog.swift (2)

198-199: 버튼 상단 간격 조정 LGTM

buttonTopInsetinset6에서 inset2로 완화하여 제목 영역과 버튼 그룹 간 거리를 줄인 변경은 의도된 디자인 QA 반영으로 보이며 문제 없습니다.


62-71: 이니셜라이저 시그니처 변경 영향 범위 점검 완료

BKDialog 호출부 전수 스캔 결과,
• 모든 호출부에서 subtitle 인자를 정상적으로 전달하고 있으며
• 빈 문자열 ""로 넘기는 패턴은 발견되지 않았습니다.

따라서 추가 수정 없이 옵셔널 변경을 적용해도 무방합니다.

src/Projects/BKDesign/Sources/Components/Label/BKLabel2.swift (1)

147-156: LabelType.small의 폰트 웨이트 확인 필요

small.label1(weight: .medium)으로 매핑되어 있습니다. 디자인 가이드(피그마)에서 regular/medium 중 어느 것이 표준인지 한 번 더 확인 부탁드립니다.

src/Projects/BKPresentation/Sources/ArchiveFlow/View/ArchiveView.swift (1)

131-135: 여백 증대 변경사항 확인(LGTM)

chipScrollView 상단 오프셋을 spacing5로 늘린 변경은 의도된 시각적 간격 조정으로 보입니다. 아래 ArchiveLayoutGuide.chipSectionInset.top(spacing3)과의 균형만 디자인 스펙과 일치하는지 최종 확인해 주세요.

src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeEmptyView.swift (1)

37-41: 카피 변경 LGTM

서브 타이틀 문구 변경은 자연스럽고 톤&매너에 부합합니다. 추가 액션 불필요합니다.

src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewHeader.swift (1)

23-27: BKLabel2 전환 LGTM

공개 API/로직 영향 없이 레이블만 BKLabel2로 교체되어 안전합니다. BKLabel2의 줄간/라인하이트가 BKLabel과 약간 다를 수 있으니 시각적 리그레션만 한번 확인 부탁드립니다.

src/Projects/BKDesign/Sources/Foundation/GraphicSystem/BKSpacing.swift (1)

16-16: spacing9 추가 LGTM

토큰 간격(36pt) 보강 좋습니다. 다른 화면(예: 온보딩)에서도 매직 넘버 대신 본 토큰 사용 권장합니다.

src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchViewController.swift (1)

248-254: 카피/버튼 레이블 변경 LGTM — 액션 매핑도 일치

좌: “나중에 하기”(dismiss), 우: “기록 시작하기”(dismiss 후 흐름 시작)로 primary/secondary 역할과 행동이 자연스럽게 매핑되어 있습니다.

src/Projects/BKPresentation/Sources/OnboardingFlow/View/OnboardingView.swift (2)

116-117: 이미지 좌우 인셋 제거 — 의도 확인 요청

imageViewhorizontalEdges를 슈퍼뷰에 맞추며 기존 좌우 인셋을 제거했습니다. 이로 인해 기기별 화면 폭에서 이미지가 가장자리까지 붙을 수 있습니다. 의도된 변경인지 확인 부탁드립니다. 가장자리 여백이 필요하다면 적정 BKInset/BKSpacing 토큰을 적용하는 편이 안전합니다.


211-213: 간격 미세 조정(spacing8 → spacing7) LGTM

타이포그래피 및 상하 레이아웃 균형을 맞추기 위한 조정으로 보이며 문제 없습니다.

src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailViewCell.swift (1)

22-31: BKLabel2 마이그레이션 및 스타일 조정 LGTM

  • emotionLabel: .label1(.semiBold)로 상향 — 강조 의도에 부합
  • creationLabel: .caption1(.regular) — 날짜 보조 정보 톤에 적절
  • pageLabel: .body2(.medium) — 가독성 무난

Also applies to: 39-43

src/Projects/BKPresentation/Sources/MainFlow/Search/View/SearchView.swift (2)

22-25: 검색바 타입을 .normal로 변경 — 의도에 부합하는 안전한 수정

디자인 톤 앤 매너 정합성을 위해 .brand → .normal 전환한 것으로 보이며, 다른 로직 영향은 없습니다.


81-84: 프로그램matic 텍스트 설정 API 추가 적절

외부에서 검색어를 주입해 UI 상태를 동기화하기 좋습니다. 간결하고 부작용 없음.

src/Projects/BKPresentation/Sources/Common/Extension/BKBottomSheetViewController+.swift (1)

108-114: 옵션 항목 좌우 인셋 축소(.inset1) — 밀도 개선 측면에서 타당

터치 타깃 높이(56) 유지하면서 좌우 여백만 줄인 변경은 보기 좋고 일관됩니다.

src/Projects/BKDesign/Sources/Components/Label/BKLabel.swift (2)

39-41: 공용 렌더 경로 통일(applyRecommended) — 유지보수성 향상

여러 진입점에서 apply()applyRecommended()로 일원화한 변경은 스타일링 일관성과 변경 용이성 측면에서 좋습니다.

Also applies to: 46-48, 53-55, 76-78, 105-107, 111-113, 117-120


154-161: paragraphStyle 인스턴스 생성이 안전함 확인됨
BKTextStyle.paragraphStyle는 computed property로 호출 시마다 새로운 NSMutableParagraphStyle 인스턴스를 생성해 반환하므로 공유로 인한 부작용은 없습니다.

src/Projects/BKDesign/Sources/Components/BottomSheet/BKBottomSheetTitleView.swift (1)

36-52: UILabel → BKLabel 마이그레이션 적절

BKLabel API로 일원화하여 스타일 제어가 명확해졌고, 자간/문단 스타일 적용 로직과도 정합적입니다.

src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/SeedReportView.swift (3)

8-13: EmotionSeed allCases 순서 변경 영향 확인

CaseIterable 순서가 바뀌면:

  • 감정 아이콘 나열 순서(라인 150 부근 for-in)가 바뀝니다.
  • 동률 시 정렬 결과의 표시 순서(요약 문구 내 나열)도 달라질 수 있습니다(정렬 안정성 보장 없음).

디자인 의도라면 OK, 아니라면 기존 순서를 유지하거나 명시적 정렬 기준을 두세요.


80-85: BKLabel2 도입으로 하이라이트 품질 개선 — 적절한 전환

highlightFont를 통해 강조 가독성이 좋아졌습니다. 타 컴포넌트의 BKLabel2 도입과도 일관됩니다.


127-129: 라벨 중앙 정렬 제약으로 레이아웃 단순화 — OK

텍스트가 단문인 현재 요구사항에는 적합합니다. 위 높이 정책만 함께 고려하면 좋겠습니다.

src/Projects/BKDesign/Sources/Components/Summary/BKBookSummaryView.swift (1)

135-136: record 모드 간격 상향(L3→L4) 타이포그래피 가독성 개선에 도움

설명 스택 이후 간격을 spacing4로 늘린 변경은 의도대로 레코드 정보 블록의 분리도를 높여줍니다. 다른 스타일에의 영향도 없고 안전합니다.

src/Projects/BKPresentation/Sources/MainFlow/BookDetail/View/BookDetailView.swift (3)

35-35: 복합명사 띄어쓰기 수정 LGTM

UI 카피 관점에서 “페이지 순”으로의 변경은 일관성 측면에서 적절합니다. 정렬 로직에는 영향 없습니다.


84-88: 동적 레이아웃 전환용 제약 레퍼런스 보유 방식 적절

zero-height, divider 연결 전환을 위해 Constraint 레퍼런스를 보관하는 접근은 유지보수에 유리합니다.


173-179: divider 상단 연결 우선순위 전환 로직 적절; 초기 상태 확인 권장

우선순위를 high/low로 교차 설정하는 방식은 의도대로 동작합니다. 다만 최초 화면 구성 시(스냅샷 적용 전) seedReport가 비어있는 경우에도 dividerTopToSeed가 우선되므로, 초기 레이아웃에서 미세한 위치 깜빡임이 있을 수 있습니다. 초기 스냅샷 호출 시점에 맞춰 우선순위를 세팅하거나, setup 단계에서 기본 상태를 ‘빈 상태’ 가정으로 맞출지 확인 부탁드립니다.

원한다면 초기 바인딩 순서를 점검하는 간단한 체크 스크립트를 제공할 수 있습니다.

Comment on lines +154 to +167
func applyRecommended() {
let customParagraphStyle = fontStyle.paragraphStyle
customParagraphStyle.alignment = alignment
customParagraphStyle.lineBreakMode = self.lineBreakMode

let extraAttributes: [NSAttributedString.Key: Any] = [
.paragraphStyle: customParagraphStyle
]

let attributedString = fontStyle.mutableAttributedString(
from: labelText,
color: labelColor,
extraAttributes: extraAttributes
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

BKTextStyle.paragraphStyle 직접 변형으로 전역 부작용 가능성 높음

fontStyle.paragraphStyle을 그대로 참조해 alignment/lineBreakMode를 변경하면, 해당 paragraphStyle이 공유 인스턴스일 경우 다른 라벨/텍스트에도 파급될 수 있습니다. 이전 apply()는 매번 새로운 NSMutableParagraphStyle을 생성했기에 안전했지만, 현재 구현은 전역 상태 오염 리스크가 있습니다. 반드시 복사본을 만들어 수정하세요.

-        let customParagraphStyle = fontStyle.paragraphStyle
-        customParagraphStyle.alignment = alignment
-        customParagraphStyle.lineBreakMode = self.lineBreakMode
+        let customParagraphStyle: NSMutableParagraphStyle = {
+            if let copy = fontStyle.paragraphStyle.mutableCopy() as? NSMutableParagraphStyle {
+                return copy
+            }
+            let newStyle = NSMutableParagraphStyle()
+            newStyle.setParagraphStyle(fontStyle.paragraphStyle)
+            return newStyle
+        }()
+        customParagraphStyle.alignment = alignment
+        customParagraphStyle.lineBreakMode = self.lineBreakMode
🤖 Prompt for AI Agents
In src/Projects/BKDesign/Sources/Components/Label/BKLabel.swift around lines 154
to 167, the code mutates fontStyle.paragraphStyle directly which can cause
global side-effects if that paragraphStyle is a shared instance; instead create
a mutable copy (e.g., let customParagraphStyle =
(fontStyle.paragraphStyle.mutableCopy() as? NSMutableParagraphStyle) ??
NSMutableParagraphStyle()), modify alignment and lineBreakMode on that copy, and
use the copy in extraAttributes so you do not mutate the original shared
paragraphStyle.

Comment on lines +54 to 56
emptyImageView.frame.size = .init(width: 112, height: 112)

[emptyImageView, labelStack, noteButton].forEach(rootStack.addArrangedSubview)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Auto Layout 환경에서 frame 사이즈 지정은 무시될 수 있습니다 — 제약으로 고정하세요

UIStackView + SnapKit 레이아웃에서 arrangedSubview의 frame을 직접 설정하면, Auto Layout 계산 시 덮어써져 의도한 112x112가 반영되지 않을 수 있습니다. 너비/높이 제약으로 고정하는 방식으로 교체해 주세요.

권장 수정:

-        emptyImageView.frame.size = .init(width: 112, height: 112)
+        // 사이즈는 오토레이아웃 제약으로 고정

setupLayout 내에 다음 제약을 추가:

// setupLayout() 내부 적절한 위치에 추가
emptyImageView.snp.makeConstraints {
    $0.width.height.equalTo(112)
}

또는 다음과 같이 size 헬퍼 사용:

emptyImageView.snp.makeConstraints { $0.size.equalTo(112) }
🤖 Prompt for AI Agents
In src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeEmptyView.swift
around lines 54 to 56, the code sets emptyImageView.frame.size directly which
can be ignored by Auto Layout in a UIStackView environment; replace the frame
sizing with explicit width/height constraints using SnapKit (e.g., add a
constraint in setupLayout to set both width and height to 112) so the image view
is fixed to 112x112 under Auto Layout.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/Projects/BKPresentation/Sources/AppCoordinator.swift (1)

58-60: 사용자-주도 닫기 시 child 정리 보장 로직 보강 제안

LoginViewController 쪽에서 닫기를 VC 자체에서 dismiss하면 LoginCoordinatorchildCoordinators에 남을 수 있습니다. 닫기(취소) 시에도 child 정리를 보장할 수 있도록 아래 중 하나를 권장합니다.

옵션 A(권장): VC → Coordinator로 위임(e.g., didTapClose()), Coordinator에서

  • parent로부터 자신을 제거(removeChild)하고
  • navigationController.dismiss(animated:) 호출

옵션 B: AppCoordinator에서 모달 프레젠테이션 델리게이트로 정리

예시:

// presentAuthFlow 내
authNavigationController.presentationController?.delegate = self

// AppCoordinator.swift 하단 등
extension AppCoordinator: UIAdaptivePresentationControllerDelegate {
    func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
        // LoginCoordinator만 찾아서 제거
        if let login = childCoordinators.first(where: { $0 is LoginCoordinator }) {
            removeChildCoordinator(login)
        }
    }
}

실제 구현 시 removeChildCoordinator(_:) 유틸이 없다면 추가 필요합니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between da6bbe1 and df7471b.

📒 Files selected for processing (5)
  • src/Projects/BKPresentation/Sources/AppCoordinator.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/AuthFlow/View/LoginViewController.swift (2 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Setting/View/SettingViewController.swift (1 hunks)
  • src/Projects/BKPresentation/Sources/MainFlow/Setting/ViewModel/SettingViewModel.swift (0 hunks)
  • src/SupportingFiles/Booket/Info.plist (2 hunks)
💤 Files with no reviewable changes (1)
  • src/Projects/BKPresentation/Sources/MainFlow/Setting/ViewModel/SettingViewModel.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Projects/BKPresentation/Sources/MainFlow/Setting/View/SettingViewController.swift
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: doyeonk429
PR: YAPP-Github/Reed-iOS#157
File: src/Projects/BKPresentation/Sources/MainFlow/Home/View/HomeViewController.swift:19-24
Timestamp: 2025-08-08T01:38:59.656Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 접근성(accessibility) 관련 개선사항은 현재 작업 중인 PR에서 즉시 처리하지 않고, 접근성 전용 PR이나 이슈를 별도로 만들어 한번에 처리하는 것을 선호한다.
Learnt from: doyeonk429
PR: YAPP-Github/Reed-iOS#157
File: src/Projects/BKPresentation/Sources/AuthFlow/View/LoginView.swift:43-45
Timestamp: 2025-08-08T01:39:15.620Z
Learning: doyeonk429는 Reed-iOS 프로젝트에서 접근성 개선 작업을 별도의 전용 PR이나 이슈에서 일괄 처리하는 것을 선호한다. 개별 기능 구현 PR에서는 접근성 관련 제안을 하지 않고, 접근성 전담 작업에서 한번에 처리하는 방식을 원한다.
📚 Learning: 2025-07-07T13:47:32.784Z
Learnt from: clxxrlove
PR: YAPP-Github/Reed-iOS#56
File: src/Projects/BKPresentation/Sources/AuthFlow/ViewModel/LoginViewModel.swift:109-111
Timestamp: 2025-07-07T13:47:32.784Z
Learning: The LoginViewModel's authenticateWithToken case in src/Projects/BKPresentation/Sources/AuthFlow/ViewModel/LoginViewModel.swift is test code and not important for implementation according to the user.

Applied to files:

  • src/Projects/BKPresentation/Sources/AuthFlow/View/LoginViewController.swift
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (4)
src/Projects/BKPresentation/Sources/AuthFlow/View/LoginViewController.swift (2)

18-23: X 닫기 버튼 추가 방향 동의 (LGTM)

풀스크린 모달 전환(아래 AppCoordinator 변경)과 맞물려 명시적 닫기 진입점을 제공하는 것이 일관적입니다. BKNavigationBarStyle 표준 구성을 그대로 활용한 점도 좋습니다.


90-92: Coordinator에 Close 이벤트 위임하도록 수정 필요

직접 self.dismiss(animated:) 호출 시 LoginCoordinator가 childCoordinators에서 제거되지 않아 메모리 누수와 후속 로직 미실행 위험이 있습니다. Base Coordinator에는 removeChildCoordinator(_:)가 구현되어 있지만, LoginCoordinator에는 이를 호출하는 진입점(didTapClose 등)이 없어 직접 활용할 수 없습니다.

수정 포인트:

  • LoginViewController.swift (handleCloseButtonTapped)
  • LoginCoordinator.swift (close/cancel 메서드 미구현)

제안하는 변경 예시:

// src/Projects/BKPresentation/Sources/AuthFlow/View/LoginViewController.swift
-    @objc private func handleCloseButtonTapped() {
-        self.dismiss(animated: true)
-    }
+    @objc private func handleCloseButtonTapped() {
+        coordinator?.didTapClose()
+    }
// src/Projects/BKPresentation/Sources/AuthFlow/Coordinator/LoginCoordinator.swift
extension LoginCoordinator {
    func didTapClose() {
        // child 정리 + 모달 해제
        parentCoordinator?.removeChildCoordinator(self)
        navigationController.dismiss(animated: true)
    }
}

위와 같이 VC는 Coordinator에 위임만 하고, Coordinator가 child 제거 및 dismiss를 일괄 처리하도록 반드시 리팩터링해야 합니다.

⛔ Skipped due to learnings
Learnt from: clxxrlove
PR: YAPP-Github/Reed-iOS#179
File: src/Projects/BKPresentation/Sources/AppCoordinator.swift:53-73
Timestamp: 2025-08-19T17:14:50.088Z
Learning: Reed-iOS 프로젝트에서는 Coordinator 패턴에서 자동 cleanup 메커니즘이 구현되어 있다. LoginViewController 등에서 coordinator?.popAndFinish() 호출 시 didFinish()가 자동으로 parentCoordinator?.removeChildCoordinator(self)를 호출하여 child coordinator를 제거한다. 따라서 수동으로 child coordinator 제거를 구현할 필요가 없다.
src/Projects/BKPresentation/Sources/AppCoordinator.swift (1)

58-60: 풀스크린 + 인터랙티브 디스미스 차단 적용 LGTM

명시적 닫기 버튼을 통한 종료 플로우와 맞물려, 스와이프 등 인터랙티브 디스미스를 비활성화한 선택이 합리적입니다.

src/SupportingFiles/Booket/Info.plist (1)

89-90: EOF 개행 추가는 문제 없습니다.

파일 포맷/도구 호환성 측면에서 긍정적입니다.

@doyeonk429
Copy link
Member

BKLabel2 네이밍 고민을 더 해야하는데,, 일단 approve할게요. 정확히 저걸 지칭할 단어가 안떠오르네요.. 😢

@clxxrlove
Copy link
Member Author

@doyeonk429 그러게요. 갑자기 BKLabel2가 생겨서 뭔가 꼬였나 했어요.

@clxxrlove clxxrlove merged commit f36a1cb into develop Aug 20, 2025
3 checks passed
@clxxrlove clxxrlove deleted the BOOK-268-fix/#175 branch August 20, 2025 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞 fix Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants