Skip to content

feat: 탭 바 UI 구현 (#1)#13

Merged
rafa-e1 merged 12 commits intodevelopfrom
feat/#1
Jun 5, 2025
Merged

feat: 탭 바 UI 구현 (#1)#13
rafa-e1 merged 12 commits intodevelopfrom
feat/#1

Conversation

@rafa-e1
Copy link
Contributor

@rafa-e1 rafa-e1 commented May 30, 2025

🚀 Pull Request

No merge conflict? Where’s the fun in that.


📌 요약

  • SwiftLint 문법 오류 수정
  • 탭 바 UI 구현

📄 상세 설명

  • 지원하지 않는 문법 및 잘못 작성한 규칙을 수정하였음
  • CocoaPods 최소 버전을 현재 프로젝트 최소 버전으로 통일하였음
  • 탭 바 아이콘(svg)을 추가하고 enum으로 정의하였음
  • Hex 기반 UIColor 생성자 추가하고 공용 색상 정의하였음
extension UIColor {

    convenience init(hex: String, alpha: CGFloat = 1.0) {
        let scanner: Scanner = Scanner(string: hex)
        _ = scanner.scanString("#")
        var hexNumber: UInt64 = 0
        scanner.scanHexInt64(&hexNumber)

        let red: CGFloat = CGFloat((hexNumber & 0xFF0000) >> 16) / 255.0
        let green: CGFloat = CGFloat((hexNumber & 0x00FF00) >> 8) / 255.0
        let blue: CGFloat = CGFloat(hexNumber & 0x0000FF) / 255.0
        let alpha: CGFloat = hex.count > 7
        ? CGFloat((hexNumber & 0xFF000000) >> 24) / 255.0
        : alpha

        self.init(red: red, green: green, blue: blue, alpha: alpha)
    }

다음과 같이 사용

UIColor(hex: "FAFAFA")

📸 구현 화면 (GIF / Screenshot)

구현 내용 SE 13 mini 15 pro
탭 바 UI

🔗 관련 이슈 (Issue)


✅ PR Check List

  • Merge 대상 브랜치가 올바른가?
  • 최종 코드가 에러 없이 잘 동작하는가?
  • 전체 변경사항이 500줄을 넘지 않는가?

Summary by CodeRabbit

  • 신규 기능

    • 홈, 위치, 북마크, 프로필 탭을 포함한 커스텀 탭 바 UI가 추가되었습니다.
    • 각 탭별로 전용 화면(홈, 지도, 북마크, 프로필)이 추가되었습니다.
    • 디자인 시스템에 아이콘 리소스와 색상 유틸리티가 도입되었습니다.
  • 스타일

    • 탭 바에 라운드 처리 및 그림자 효과가 적용되어 시각적 완성도가 향상되었습니다.
  • 환경 설정

    • iOS 최소 지원 버전이 16.0으로 상향되었습니다.
    • SwiftLint 설정이 최신화 및 정비되었습니다.

@rafa-e1 rafa-e1 requested a review from alstjr7437 May 30, 2025 10:52
@rafa-e1 rafa-e1 self-assigned this May 30, 2025
@rafa-e1 rafa-e1 added the ✨ Feature 기능 구현 label May 30, 2025
@coderabbitai
Copy link

coderabbitai bot commented May 30, 2025

"""

Walkthrough

이 변경사항은 커스텀 탭 바 UI를 도입하고, 각 탭(홈, 지도, 북마크, 프로필)에 해당하는 뷰 컨트롤러와 아이콘 에셋, 색상 시스템을 추가합니다. 또한, 기존 ViewController를 제거하고, 앱의 루트 뷰 컨트롤러를 MainTabBarController로 교체하였습니다. SwiftLint 및 Podfile 등 환경설정도 일부 수정되었습니다.

Changes

파일/경로 그룹 변경 요약
MatzipBook/MatzipBook.xcodeproj/project.pbxproj, Podfile Xcode 프로젝트 파일 내부 UUID 변경 및 iOS 타겟 버전 16.0 설정, post_install 훅 추가
MatzipBook/.swiftlint.yml SwiftLint 설정 리팩토링, 규칙 추가 및 제거, 심각도 명시, 주석 정비
MatzipBook/MatzipBook/Application/SceneDelegate.swift 루트 뷰 컨트롤러를 기존 ViewController에서 MainTabBarController로 변경
MatzipBook/MatzipBook/Presentation/ViewController.swift 기존 ViewController 클래스 및 파일 삭제
MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift, MainTab.swift 커스텀 탭 바 컨트롤러 구현 및 탭 enum 정의, 각 탭별 뷰 컨트롤러 연결
MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift, .../Bookmark/BookmarkViewController.swift, .../Map/MapViewController.swift, .../Profile/ProfileViewController.swift 홈, 북마크, 지도, 프로필 탭용 뷰 컨트롤러 신규 추가, 배경색 설정 포함
MatzipBook/MatzipBook/Core/DesignSystem/Foundation/MatzipIcon.swift 탭 바 아이콘 식별용 enum MatzipIcon 추가 (선택/비선택 상태 포함)
MatzipBook/MatzipBook/Core/DesignSystem/Foundation/UIColor+.swift UIColor 확장에 16진수 색상 초기화기 및 주요 색상 프로퍼티 추가
MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/* 탭 바 아이콘 SVG 에셋 및 Contents.json 메타데이터 파일 추가 (선택/비선택 상태별)

Sequence Diagram(s)

sequenceDiagram
    participant App as App Launch
    participant SceneDelegate
    participant MainTabBarController
    participant MainTab
    participant VC as 각 Tab의 ViewController

    App->>SceneDelegate: 앱 실행 및 씬 연결
    SceneDelegate->>MainTabBarController: 루트 뷰 컨트롤러로 생성
    MainTabBarController->>MainTab: 탭 목록 순회
    MainTab->>VC: 각 탭별 ViewController 반환
    MainTabBarController->>MainTabBarController: 탭 바 UI 및 커스텀 뷰 설정
    MainTabBarController->>App: 탭 바 UI 표시 및 동작
Loading

Assessment against linked issues

Objective (이슈 번호) Addressed Explanation
커스텀 탭 바 구현 (#1)
탭 바 아이콘 및 색상 에셋 추가 (#1)
각 탭을 구성하는 뷰 추가 (#1)

Poem

🐰
탭 바 위에 햇살이 내려와
네 가지 탭이 깡충깡충 춤을 춰요
홈, 지도, 북마크, 프로필까지
아이콘 반짝, 배경은 포근
토끼도 좋아할 새 옷 입은 앱
이제 더 깔끔하게,
우리 모두 즐겁게!

"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28a68e1 and 1ff5ef5.

📒 Files selected for processing (1)
  • MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • 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.

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: 4

🧹 Nitpick comments (6)
MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift (1)

10-17: 코드 중복을 줄이기 위한 리팩토링을 고려해보세요.

현재 HomeViewController, BookmarkViewController, MapViewController와 동일한 구현 패턴을 사용하고 있습니다. 향후 공통 로직이 추가될 가능성을 고려하여 베이스 뷰 컨트롤러를 만드는 것을 권장합니다.

다음과 같은 베이스 클래스를 생성할 수 있습니다:

class BaseViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.mainBackgroundColor
    }
}

그리고 각 뷰 컨트롤러에서 상속:

-class ProfileViewController: UIViewController {
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        view.backgroundColor = UIColor.mainBackgroundColor
-    }
-}
+class ProfileViewController: BaseViewController {
+}
MatzipBook/MatzipBook/Core/DesignSystem/Foundation/MatzipIcon.swift (1)

8-8: 불필요한 import를 제거하는 것을 고려해보세요.

현재 코드에서는 Foundation 프레임워크의 기능을 사용하지 않으므로 import 문이 불필요할 수 있습니다.

-import Foundation
MatzipBook/MatzipBook/Presentation/Main/MainTab.swift (1)

31-38: 뷰 컨트롤러 인스턴스 생성 방식 최적화를 고려해보세요.

현재 구현은 올바르게 작동하지만, viewController 속성에 접근할 때마다 새로운 인스턴스를 생성합니다. 탭바 사용 패턴에 따라 인스턴스를 캐싱하는 것을 고려할 수 있습니다.

성능 최적화가 필요한 경우 다음과 같이 lazy 속성을 활용할 수 있습니다:

// MainTabBarController에서 한 번만 생성하여 사용
let tabs = MainTab.allCases.map { $0.viewController }

하지만 현재 구현도 충분히 명확하고 이해하기 쉬우므로, 성능 이슈가 확인되기 전까지는 현재 구조를 유지하는 것도 좋습니다.

MatzipBook/MatzipBook/Core/DesignSystem/Foundation/UIColor+.swift (1)

12-26: 입력 유효성 검사를 추가하는 것을 권장합니다.

현재 구현에서는 잘못된 형식의 hex 문자열이 입력되어도 실패하지 않고 예상치 못한 색상을 반환할 수 있습니다.

다음과 같은 개선사항을 고려해보세요:

 convenience init(hex: String, alpha: CGFloat = 1.0) {
+    let cleanHex = hex.trimmingCharacters(in: .whitespacesAndNewlines)
+    guard cleanHex.count >= 6 else {
+        self.init(red: 0, green: 0, blue: 0, alpha: alpha)
+        return
+    }
+    
-    let scanner: Scanner = Scanner(string: hex)
+    let scanner: Scanner = Scanner(string: cleanHex)
     _ = scanner.scanString("#")
     var hexNumber: UInt64 = 0
-    scanner.scanHexInt64(&hexNumber)
+    guard scanner.scanHexInt64(&hexNumber) else {
+        self.init(red: 0, green: 0, blue: 0, alpha: alpha)
+        return
+    }
MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift (2)

34-34: 매직 넘버를 상수로 정의하는 것을 권장합니다.

코드에서 사용되는 숫자값들(68, 24, 10)을 의미있는 상수로 정의하면 유지보수성이 향상됩니다.

다음과 같이 상수를 정의하는 것을 권장합니다:

+    // MARK: - Constants
+    
+    private enum Constants {
+        static let tabBarHeight: CGFloat = 68
+        static let cornerRadius: CGFloat = 24
+        static let shadowRadius: CGFloat = 10
+        static let imageInsetTop: CGFloat = 10
+    }

그리고 해당 값들을 상수로 교체:

-        let height: CGFloat = view.safeAreaInsets.bottom + 68
+        let height: CGFloat = view.safeAreaInsets.bottom + Constants.tabBarHeight

Also applies to: 70-70, 75-75, 80-80


77-82: 비동기 섀도우 패스 설정을 개선할 수 있습니다.

현재 DispatchQueue.main.async를 사용하고 있지만, 레이아웃이 완료된 후 직접 설정하는 것이 더 안전할 수 있습니다.

다음과 같은 개선을 고려해보세요:

-        DispatchQueue.main.async {
-            self.customTabBarView.layer.shadowPath = UIBezierPath(
-                roundedRect: self.customTabBarView.bounds,
-                cornerRadius: 24
-            ).cgPath
-        }
+        customTabBarView.layoutIfNeeded()
+        customTabBarView.layer.shadowPath = UIBezierPath(
+            roundedRect: customTabBarView.bounds,
+            cornerRadius: Constants.cornerRadius
+        ).cgPath
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d66c48e and 188257b.

⛔ Files ignored due to path filters (9)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/bookmark_selected.svg is excluded by !**/*.svg
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/bookmark_unselected.svg is excluded by !**/*.svg
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/home_selected.svg is excluded by !**/*.svg
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/home_unselected.svg is excluded by !**/*.svg
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/location_selected.svg is excluded by !**/*.svg
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/location_unselected.svg is excluded by !**/*.svg
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/person_selected.svg is excluded by !**/*.svg
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/person_unselected.svg is excluded by !**/*.svg
  • MatzipBook/Podfile.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • MatzipBook/.swiftlint.yml (1 hunks)
  • MatzipBook/MatzipBook.xcodeproj/project.pbxproj (8 hunks)
  • MatzipBook/MatzipBook/Application/SceneDelegate.swift (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Foundation/MatzipIcon.swift (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Foundation/UIColor+.swift (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/Contents.json (1 hunks)
  • MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift (1 hunks)
  • MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift (1 hunks)
  • MatzipBook/MatzipBook/Presentation/Main/MainTab.swift (1 hunks)
  • MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift (1 hunks)
  • MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift (1 hunks)
  • MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift (1 hunks)
  • MatzipBook/MatzipBook/Presentation/ViewController.swift (0 hunks)
  • MatzipBook/Podfile (1 hunks)
💤 Files with no reviewable changes (1)
  • MatzipBook/MatzipBook/Presentation/ViewController.swift
🧰 Additional context used
🧬 Code Graph Analysis (4)
MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift (3)
MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift (3)
MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift (3)
MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift (3)
MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift (1)
  • viewDidLoad (12-16)
MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift (1)
  • viewDidLoad (12-16)
🔇 Additional comments (19)
MatzipBook/Podfile (2)

1-1: 플랫폼 설정이 올바르게 구성되었습니다.

iOS 16.0으로 배포 타겟을 명시적으로 설정한 것이 좋습니다. 이는 프로젝트의 최소 요구사항과 일치합니다.


9-15: post_install 훅이 적절하게 추가되었습니다.

모든 팟의 IPHONEOS_DEPLOYMENT_TARGET을 16.0으로 통일하는 것은 의존성 간의 일관성을 보장하는 좋은 관례입니다. 이를 통해 빌드 시 발생할 수 있는 배포 타겟 불일치 문제를 예방할 수 있습니다.

MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/Contents.json (1)

1-12: 에셋 카탈로그 구조가 올바르게 정의되었습니다.

표준 Xcode 에셋 카탈로그 JSON 형식을 따르고 있으며, SVG 형식의 아이콘을 사용하는 것은 해상도 독립적이어서 다양한 디스플레이 크기에 대응하기에 좋은 선택입니다.

MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/Contents.json (1)

1-6: 에셋 카탈로그 메타데이터가 적절하게 구성되었습니다.

Icons 폴더를 위한 표준 Xcode 메타데이터 파일이 올바르게 생성되었습니다.

MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/Contents.json (1)

1-12: 에셋 카탈로그가 일관되게 구성되었습니다.

다른 아이콘 에셋들과 동일한 패턴으로 구성되어 있어 일관성이 유지되고 있으며, SVG 형식 사용으로 확장성도 보장됩니다.

MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/Contents.json (1)

1-12: Asset catalog 구조가 올바르게 구현되었습니다.

SVG 파일을 사용한 universal idiom 설정이 적절하며, iOS 표준 asset catalog 형식을 올바르게 따르고 있습니다.

MatzipBook/MatzipBook/Application/SceneDelegate.swift (1)

22-22:

Details

✅ Verification successful

루트 뷰 컨트롤러 변경이 적절합니다.

MainTabBarController로의 변경이 탭 바 UI 구현 목적에 부합합니다. MainTabBarController가 올바르게 구현되어 있는지 확인하세요.

다음 스크립트를 실행하여 MainTabBarController의 구현을 확인하세요:


🏁 Script executed:

#!/bin/bash
# MainTabBarController 클래스가 올바르게 정의되어 있는지 확인
ast-grep --pattern 'class MainTabBarController: $_ {
  $$$
}'

Length of output: 63


추가 확인을 위해 MainTabBarController 파일과 정의 위치를 검색해 보세요:


🏁 Script executed:

#!/bin/bash
# MainTabBarController.swift 파일 존재 확인
fd MainTabBarController.swift

echo "— 클래스 정의 검색 —"
# 클래스 정의가 있는지 확인
rg "class MainTabBarController" -n .

Length of output: 301


루트 뷰 컨트롤러 변경 승인

MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift 파일의 10번째 줄에서

final class MainTabBarController: UITabBarController {  }

로 정의된 것을 확인했습니다. 탭 기반 UI 도입을 위한 변경이 적절하므로 승인합니다.

MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/Contents.json (1)

1-12: Asset catalog 구조가 일관성 있게 구현되었습니다.

다른 아이콘 asset catalog와 동일한 구조를 사용하여 일관성을 유지하고 있으며, SVG 형식의 사용이 적절합니다.

MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/Contents.json (1)

1-12:

Details

✅ Verification successful

선택된 상태 아이콘이 올바르게 구현되었습니다.

선택된/선택되지 않은 상태의 아이콘 쌍이 일관된 명명 규칙을 따르고 있어 좋습니다. 탭 바 구현에 필요한 모든 아이콘이 준비되었는지 확인하세요.

다음 스크립트를 실행하여 모든 필요한 탭 바 아이콘이 있는지 확인하세요:


🏁 Script executed:

#!/bin/bash
# 탭 바에 필요한 모든 아이콘 asset이 존재하는지 확인
echo "탭 바 아이콘 asset 확인:"
fd "ic_.*\.imageset" MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ --type d | sort

Length of output: 976


모든 탭 바 아이콘 준비 완료 확인

  • ic_bookmark, ic_home, ic_location, ic_person의 selected/unselected 쌍이 모두 존재함을 스크립트 실행으로 확인했습니다.
  • JSON 구조 및 명명 규칙도 일관성이 유지되고 있습니다.

이대로 머지 승인합니다.

MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift (1)

12-16: MapViewController 배경색 설정 일관성
view.backgroundColor = UIColor.mainBackgroundColor가 다른 뷰 컨트롤러(Home, Bookmark, Profile)와 동일하게 적용되어 있어 디자인 시스템과 잘 통일되었습니다.

MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift (1)

12-16: BookmarkViewController 배경색 설정 일관성
다른 탭 뷰 컨트롤러와 마찬가지로 mainBackgroundColor를 사용해 일관된 테마가 유지되고 있습니다.

MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift (1)

10-17: 탭바 구현을 위한 기본 구조가 잘 설계되었습니다.

HomeViewController가 올바르게 구현되었으며, 다른 뷰 컨트롤러들과 일관된 패턴을 따르고 있습니다. UIColor.mainBackgroundColor를 사용하여 디자인 시스템을 잘 준수하고 있습니다.

MatzipBook/MatzipBook/Core/DesignSystem/Foundation/MatzipIcon.swift (1)

10-19: 아이콘 관리를 위한 enum 설계가 우수합니다.

String raw value를 사용한 enum 설계가 매우 적절하며, 일관된 네이밍 컨벤션을 따르고 있습니다. 선택된/선택되지 않은 상태의 아이콘을 체계적으로 관리할 수 있는 좋은 구조입니다.

MatzipBook/MatzipBook/Presentation/Main/MainTab.swift (1)

10-11: 탭 관리를 위한 enum 설계가 훌륭합니다.

Int와 CaseIterable을 사용한 enum 설계가 탭바 구현에 매우 적합합니다. 탭의 순서와 반복을 효율적으로 관리할 수 있는 좋은 구조입니다.

MatzipBook/MatzipBook.xcodeproj/project.pbxproj (1)

11-11: Xcode 프로젝트 파일의 자동 생성된 변경사항입니다.

CocoaPods 통합과 관련된 UUID 참조들이 업데이트되었습니다. 이러한 변경사항들은 Xcode에서 자동으로 생성되는 것으로, 프로젝트 구조 변경이나 의존성 업데이트 시 정상적으로 발생합니다.

Also applies to: 17-19, 48-48, 62-62, 74-77, 85-86, 98-98, 181-181, 218-218, 254-254

MatzipBook/MatzipBook/Core/DesignSystem/Foundation/UIColor+.swift (1)

28-29: 디자인 시스템 색상 정의가 잘 구성되어 있습니다.

mainBackgroundColorshadowColor가 명확하게 정의되어 있어 앱 전반에서 일관된 색상 사용이 가능합니다.

MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift (2)

33-44: 탭 바 프레임 계산 로직이 잘 구현되어 있습니다.

Safe area를 고려한 동적 높이 계산과 프레임 업데이트가 적절하게 처리되었습니다.


46-64: 뷰 컨트롤러 설정 로직이 깔끔하게 구현되어 있습니다.

MainTab.allCases를 활용한 동적 탭 생성과 이미지 인셋 설정이 잘 구현되었습니다.

MatzipBook/.swiftlint.yml (1)

1-73: SwiftLint 설정이 매우 잘 구성되어 있습니다.

한국어 주석으로 각 규칙의 목적이 명확하게 설명되어 있고, 적절한 심각도 레벨과 임계값이 설정되어 있습니다. 특히 다음 점들이 우수합니다:

  • force_unwrappingforce_cast를 에러로 설정하여 안전한 코딩 유도
  • 파일 길이와 라인 길이에 합리적인 제한 설정
  • URL, 주석, 보간 문자열에 대한 예외 처리
  • 코드 일관성을 위한 다양한 스타일 규칙들

이러한 설정은 프로젝트의 코드 품질 향상에 크게 기여할 것입니다.

Comment on lines 1 to 12
{
"images" : [
{
"filename" : "person_selected.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

SVG 자산의 벡터 보존 및 스케일 속성 추가 필요
현재 person_selected.svg만 지정되어 있어, Xcode Asset Catalog 내에서 벡터 데이터를 올바르게 처리하지 못할 수 있습니다. scale 필드("1x")와 properties.preserves-vector-data: true 속성을 명시하여 SVG(또는 PDF) 자산을 벡터로 보존하도록 설정하는 것을 권장합니다.

 {
   "images" : [
     {
       "filename" : "person_selected.svg",
       "idiom" : "universal",
+      "scale" : "1x"
     }
   ],
+  "properties": {
+    "preserves-vector-data": true
+  },
   "info" : {
     "author" : "xcode",
     "version" : 1
   }
 }
📝 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
{
"images" : [
{
"filename" : "person_selected.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "person_selected.svg",
"idiom" : "universal",
"scale" : "1x"
}
],
"properties" : {
"preserves-vector-data" : true
},
"info" : {
"author" : "xcode",
"version" : 1
}
}
🤖 Prompt for AI Agents
In
MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/Contents.json
lines 1 to 12, the JSON lacks the "scale" field and
"properties.preserves-vector-data" attribute needed for proper vector handling
of the SVG asset. Add "scale": "1x" to the image dictionary and include
"properties": { "preserves-vector-data": true } to ensure Xcode treats the SVG
as a vector asset and preserves its scalability.

Comment on lines 1 to 12
{
"images" : [
{
"filename" : "person_unselected.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

SVG 자산의 벡터 보존 및 스케일 속성 추가 필요
person_unselected.svg도 동일하게 scaleproperties.preserves-vector-data를 추가하여 벡터 자산으로 보존되도록 설정해주세요.

 {
   "images" : [
     {
       "filename" : "person_unselected.svg",
       "idiom" : "universal",
+      "scale" : "1x"
     }
   ],
+  "properties": {
+    "preserves-vector-data": true
+  },
   "info" : {
     "author" : "xcode",
     "version" : 1
   }
 }
📝 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
{
"images" : [
{
"filename" : "person_unselected.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "person_unselected.svg",
"idiom" : "universal",
"scale" : "1x"
}
],
"properties" : {
"preserves-vector-data" : true
},
"info" : {
"author" : "xcode",
"version" : 1
}
}
🤖 Prompt for AI Agents
In
MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/Contents.json
lines 1 to 12, the JSON asset file for person_unselected.svg lacks the scale and
properties.preserves-vector-data fields. Add a "scale" field with the value "1x"
and a "properties" object containing "preserves-vector-data" set to true inside
the image dictionary to ensure the SVG is preserved as a vector asset and scales
correctly.

Comment on lines 1 to 12
{
"images" : [
{
"filename" : "location_selected.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

SVG 자산의 벡터 보존 및 스케일 속성 추가 필요
location_selected.svg 역시 벡터로 보존될 수 있도록 scale: "1x"properties.preserves-vector-data: true를 추가해주세요.

 {
   "images" : [
     {
       "filename" : "location_selected.svg",
       "idiom" : "universal",
+      "scale" : "1x"
     }
   ],
+  "properties": {
+    "preserves-vector-data": true
+  },
   "info" : {
     "author" : "xcode",
     "version" : 1
   }
 }
📝 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
{
"images" : [
{
"filename" : "location_selected.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "location_selected.svg",
"idiom" : "universal",
"scale" : "1x"
}
],
"properties" : {
"preserves-vector-data" : true
},
"info" : {
"author" : "xcode",
"version" : 1
}
}
🤖 Prompt for AI Agents
In
MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/Contents.json
lines 1 to 12, the SVG asset lacks vector preservation and scale properties. Add
"scale": "1x" and "properties": { "preserves-vector-data": true } to the image
dictionary to ensure the SVG is preserved as a vector and scales correctly.

Copy link
Member

@alstjr7437 alstjr7437 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!! property 등이 MARK 문으로 잘보여서 좋네요!!

혹시 MARK문을 할때
MARK: - - 객체 밖에
MARK: - 객체 안에

이렇게 하면 minimap 볼때 더 편할 것 같은데 어떠신가요?!

@rafa-e1
Copy link
Contributor Author

rafa-e1 commented Jun 5, 2025

저는 미니맵보다는 점프 바로 구조를 확인하는 편인데 이 경우 // MARK:만 쓰먄 중간 구분선이 보이지 않아서 섹션 가독성이 조금 떨어지더라고요. 그래서 저는 내부에도 // MARK: -를 사용하는 편이에요. 이렇게 하면 코드가 길어졌을 때도 시각적으로 확실히 나뉘고 점프 바에서도 구분선이 잘 보여서 개인적으로는 더 명확하더라고요. 그래도 말씀하신 방식도 충분히 의미 있고 팀 컨벤션이나 상황에 따라 조절해보는 것도 좋을 것 같아요. 좋은 의견 감사합니다!

//MARK: - //MARK:
스크린샷 2025-06-05 17 24 09 스크린샷 2025-06-05 17 24 25

@rafa-e1 rafa-e1 merged commit 7ffc72b into develop Jun 5, 2025
2 checks passed
@rafa-e1 rafa-e1 deleted the feat/#1 branch June 5, 2025 08:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

탭 바 UI 구현

2 participants