diff --git a/MatzipBook/.swiftlint.yml b/MatzipBook/.swiftlint.yml index f4a2857..c9a28fc 100644 --- a/MatzipBook/.swiftlint.yml +++ b/MatzipBook/.swiftlint.yml @@ -1,99 +1,72 @@ -# 검사 제외할 디렉토리 (라이브러리 등 무시 대상) +# 무시할 디렉토리 (라이브러리 코드 등 Lint 제외) excluded: - Pods -# 선택적으로 활성화하는 고급 룰들 +# 선택적으로 활성화한 룰들 (opt-in rule은 명시하지 않으면 비활성 상태) opt_in_rules: - - force_unwrapping - - force_cast - - discouraged_optional_boolean - - empty_count - - empty_enum_arguments # 불필요한 열거형 인자 제거 - - explicit_init # 명시적인 이니셜라이저 사용 - - fatal_error_message # fatalError에 메시지 포함 요구 - - multiline_function_chains # 체이닝 시 줄바꿈 강제 - - override_in_extension # 확장에서 override 제한 - - sorted_imports # import 순서 정렬 - - unused_closure_parameter - - unused_declaration # 사용되지 않는 선언 제거 - - vertical_parameter_alignment_on_call # 함수 호출 시 파라미터 정렬 - - yoda_condition # 조건문에서 상수 == 변수 패턴 제한 - - closure_end_indentation + - closure_parameter_position # 클로저 파라미터는 { 와 같은 줄에 위치해야 함 + - discouraged_optional_boolean # 옵셔널 Bool 사용을 지양 (ex. Bool? → 명확한 처리 유도) + - empty_count # collection.count == 0 → collection.isEmpty 권장 + - empty_enum_arguments # 열거형 case에서 불필요한 괄호 제거 (e.g. case .a() → .a) + - explicit_init # 명시적 이니셜라이저 사용 유도 (암시적 init 방지) + - explicit_type_interface # 프로퍼티 선언 시 타입 명시 요구 (유추 방지) + - fatal_error_message # fatalError에는 반드시 설명 메시지를 포함해야 함 + - force_cast # 강제 형변환 (`as!`) 사용 금지 + - force_try # `try!` 사용 시 경고 + - force_unwrapping # 옵셔널 강제 언래핑 (`!`) 금지 + - multiline_function_chains # 체이닝 호출은 줄바꿈하여 가독성 확보 + - override_in_extension # extension에서 override 금지 (클래스 내부에서만 허용) + - sorted_imports # import문 알파벳 순으로 정렬 + - syntactic_sugar # Array() → [Int]() 같은 간결한 문법 사용 유도 + - vertical_parameter_alignment # 함수 호출 시 파라미터 세로 정렬 + - yoda_condition # 상수를 왼쪽에 두는 조건문 제한 (e.g. 5 == count → count == 5) + +# 클로저 파라미터 위치 스타일 설정 +closure_parameter_position: + severity: warning -nesting: - type_level: - warning: 2 +# 콜론(:) 위치 및 공백 설정 +colon: + apply_to_dictionaries: true # 딕셔너리에서도 콜론 스타일 적용 + flexible_right_spacing: false # 콜론 뒤에는 정확히 한 칸만 허용 -# 줄 길이 제한 설정 -line_length: - warning: 100 # 100자를 초과할 시 경고 - ignores_urls: true # URL을 최대 길이 규칙에서 제외 - ignores_comments: true # 주석은 최대 길이 규칙에서 제외 - ignores_interpolated_strings: true # 문자열 보간법 사용 시 최대 길이 규칙 제외 +# 타입 인터페이스 명시 강제 (유추 방지) +explicit_type_interface: + severity: warning +# 파일 전체 길이 제한 (길어지면 리팩터링 유도) file_length: - warning: 500 - -# 강제 부분 error 설정 -force_unwrapping: - severity: error + warning: 500 # 500줄 넘으면 경고 + error: 800 # 800줄 넘으면 에러 +# 강제 캐스팅은 무조건 에러 force_cast: severity: error -# 들여쓰기 및 공백 관련 룰 -trailing_whitespace: - ignores_empty_lines: true - -colon: - flexible_right_spacing: false - apply_to_dictionaries: true - -comma: - mandatory_comma: true - -# 연산자 공백 강제 -operator_usage_whitespace: +# try! 사용 시 경고 +force_try: severity: warning -# 클로저 관련 룰 -closure_spacing: - always_spaced: true - allow_trailing_closure: true - -closure_parameter_position: - severity: warning - -# self 키워드 사용 관련 설정 -explicit_self: - severity: warning - mode: unnecessary_only - -# 상속을 허용하지 않는 클래스는 final 명시 -final_class: - severity: warning - -# 사용하지 않는 옵셔널 바인딩 제한 -unused_optional_binding: - severity: warning - -# 문서화 주석 사용 권장 -documentation: - severity: warning - -# import 순서 및 중복 관리 -sorted_imports: - severity: warning - configuration: - sorted_imports: true - grouping: 'builtin,external' +# !로 옵셔널 언래핑하면 에러 +force_unwrapping: + severity: error -duplicate_imports: warning +# 한 줄 최대 길이 제한 (URL, 주석, 보간 문자열은 예외) +line_length: + warning: 100 + ignores_urls: true + ignores_comments: true + ignores_interpolated_strings: true -# 명시적 타입 표현 강제 (튜플 제외 가능) -explicit_type_interface: - exclude_typed_tuples: false +# 중첩 수준 제한 (클래스 안에 클래스 등) +nesting: + type_level: + warning: 2 # 2단계 이상 중첩되면 경고 -# Array/Dictionary 표현식 통일 +# 문법 축약형(syntactic sugar) 강제 syntactic_sugar: severity: warning + +# 빈 줄의 후행 공백은 허용, 나머지는 제거 +trailing_whitespace: + ignores_empty_lines: true diff --git a/MatzipBook/MatzipBook.xcodeproj/project.pbxproj b/MatzipBook/MatzipBook.xcodeproj/project.pbxproj index e89c7bf..8d0fb0c 100644 --- a/MatzipBook/MatzipBook.xcodeproj/project.pbxproj +++ b/MatzipBook/MatzipBook.xcodeproj/project.pbxproj @@ -8,15 +8,15 @@ /* Begin PBXBuildFile section */ 05493BC92DDB728C00C458AA /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = 05493BC82DDB728C00C458AA /* .swiftlint.yml */; }; - 6979A438999189D38595F136 /* Pods_MatzipBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF0615D904C5C97DFA75012 /* Pods_MatzipBook.framework */; }; + EE820D2339961F6A8AAE8A1A /* Pods_MatzipBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B17FD6FD158AF6D146DD4EC6 /* Pods_MatzipBook.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 05493BC82DDB728C00C458AA /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; 05E5F5B72D956A6A00F0CB97 /* MatzipBook.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MatzipBook.app; sourceTree = BUILT_PRODUCTS_DIR; }; - AABB485B393096F592287E72 /* Pods-MatzipBook.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatzipBook.debug.xcconfig"; path = "Target Support Files/Pods-MatzipBook/Pods-MatzipBook.debug.xcconfig"; sourceTree = ""; }; - AFD3FA43BE21ADE1EA6436F3 /* Pods-MatzipBook.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatzipBook.release.xcconfig"; path = "Target Support Files/Pods-MatzipBook/Pods-MatzipBook.release.xcconfig"; sourceTree = ""; }; - CDF0615D904C5C97DFA75012 /* Pods_MatzipBook.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MatzipBook.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B17FD6FD158AF6D146DD4EC6 /* Pods_MatzipBook.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MatzipBook.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B34481B9F19C8F2D52AE4B3D /* Pods-MatzipBook.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatzipBook.debug.xcconfig"; path = "Target Support Files/Pods-MatzipBook/Pods-MatzipBook.debug.xcconfig"; sourceTree = ""; }; + E95B702563DD4A03C2138566 /* Pods-MatzipBook.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatzipBook.release.xcconfig"; path = "Target Support Files/Pods-MatzipBook/Pods-MatzipBook.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ @@ -45,7 +45,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6979A438999189D38595F136 /* Pods_MatzipBook.framework in Frameworks */, + EE820D2339961F6A8AAE8A1A /* Pods_MatzipBook.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,7 +59,7 @@ 05E5F5B92D956A6A00F0CB97 /* MatzipBook */, 05E5F5B82D956A6A00F0CB97 /* Products */, E62E82F3E597652647D93078 /* Pods */, - 733CF51A563DB87AD2F2BB31 /* Frameworks */, + D2420DE4D574E2D7D29CAB24 /* Frameworks */, ); sourceTree = ""; }; @@ -71,10 +71,10 @@ name = Products; sourceTree = ""; }; - 733CF51A563DB87AD2F2BB31 /* Frameworks */ = { + D2420DE4D574E2D7D29CAB24 /* Frameworks */ = { isa = PBXGroup; children = ( - CDF0615D904C5C97DFA75012 /* Pods_MatzipBook.framework */, + B17FD6FD158AF6D146DD4EC6 /* Pods_MatzipBook.framework */, ); name = Frameworks; sourceTree = ""; @@ -82,8 +82,8 @@ E62E82F3E597652647D93078 /* Pods */ = { isa = PBXGroup; children = ( - AABB485B393096F592287E72 /* Pods-MatzipBook.debug.xcconfig */, - AFD3FA43BE21ADE1EA6436F3 /* Pods-MatzipBook.release.xcconfig */, + B34481B9F19C8F2D52AE4B3D /* Pods-MatzipBook.debug.xcconfig */, + E95B702563DD4A03C2138566 /* Pods-MatzipBook.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -95,7 +95,7 @@ isa = PBXNativeTarget; buildConfigurationList = 05E5F5CA2D956A6C00F0CB97 /* Build configuration list for PBXNativeTarget "MatzipBook" */; buildPhases = ( - 229A18452F0F1269E3EE4A8C /* [CP] Check Pods Manifest.lock */, + B3FD7D6A459785F2C512B25D /* [CP] Check Pods Manifest.lock */, 05493BC72DDB71D900C458AA /* SwiftLint Script */, 05E5F5B32D956A6A00F0CB97 /* Sources */, 05E5F5B42D956A6A00F0CB97 /* Frameworks */, @@ -178,7 +178,7 @@ shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; }; - 229A18452F0F1269E3EE4A8C /* [CP] Check Pods Manifest.lock */ = { + B3FD7D6A459785F2C512B25D /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -215,7 +215,7 @@ /* Begin XCBuildConfiguration section */ 05E5F5CB2D956A6C00F0CB97 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AABB485B393096F592287E72 /* Pods-MatzipBook.debug.xcconfig */; + baseConfigurationReference = B34481B9F19C8F2D52AE4B3D /* Pods-MatzipBook.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -251,7 +251,7 @@ }; 05E5F5CC2D956A6C00F0CB97 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AFD3FA43BE21ADE1EA6436F3 /* Pods-MatzipBook.release.xcconfig */; + baseConfigurationReference = E95B702563DD4A03C2138566 /* Pods-MatzipBook.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; diff --git a/MatzipBook/MatzipBook/Application/SceneDelegate.swift b/MatzipBook/MatzipBook/Application/SceneDelegate.swift index 1206a96..2a31d67 100644 --- a/MatzipBook/MatzipBook/Application/SceneDelegate.swift +++ b/MatzipBook/MatzipBook/Application/SceneDelegate.swift @@ -19,7 +19,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { guard let windowScene = (scene as? UIWindowScene) else { return } window = UIWindow(windowScene: windowScene) - window?.rootViewController = ViewController() + window?.rootViewController = MainTabBarController() window?.makeKeyAndVisible() } diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Foundation/MatzipIcon.swift b/MatzipBook/MatzipBook/Core/DesignSystem/Foundation/MatzipIcon.swift new file mode 100644 index 0000000..614967c --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Foundation/MatzipIcon.swift @@ -0,0 +1,19 @@ +// +// MatzipIcon.swift +// MatzipBook +// +// Created by RAFA on 5/30/25. +// + +import Foundation + +enum MatzipIcon: String { + case icBookmarkSelected = "ic_bookmark_selected" + case icBookmarkUnselected = "ic_bookmark_unselected" + case icHomeSelected = "ic_home_selected" + case icHomeUnselected = "ic_home_unselected" + case icLocationSelected = "ic_location_selected" + case icLocationUnselected = "ic_location_unselected" + case icPersonSelected = "ic_person_selected" + case icPersonUnselected = "ic_person_unselected" +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Foundation/UIColor+.swift b/MatzipBook/MatzipBook/Core/DesignSystem/Foundation/UIColor+.swift new file mode 100644 index 0000000..39d9842 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Foundation/UIColor+.swift @@ -0,0 +1,30 @@ +// +// UIColor+.swift +// MatzipBook +// +// Created by RAFA on 5/30/25. +// + +import UIKit + +extension UIColor { + + convenience init(hex: String, alpha defaultAlpha: 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 finalAlpha: CGFloat = hex.count > 7 + ? CGFloat((hexNumber & 0xFF000000) >> 24) / 255.0 + : defaultAlpha + + self.init(red: red, green: green, blue: blue, alpha: finalAlpha) + } + + static let mainBackgroundColor: UIColor = UIColor(hex: "FAFAFA") + static let shadowColor: UIColor = UIColor(hex: "000000", alpha: 0.13) +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/Contents.json new file mode 100644 index 0000000..26ad041 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "bookmark_selected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/bookmark_selected.svg b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/bookmark_selected.svg new file mode 100644 index 0000000..95a074e --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_selected.imageset/bookmark_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/Contents.json new file mode 100644 index 0000000..75ae339 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "bookmark_unselected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/bookmark_unselected.svg b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/bookmark_unselected.svg new file mode 100644 index 0000000..e0fd48d --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_bookmark_unselected.imageset/bookmark_unselected.svg @@ -0,0 +1,3 @@ + + + diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/Contents.json new file mode 100644 index 0000000..5a1073c --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "home_selected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/home_selected.svg b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/home_selected.svg new file mode 100644 index 0000000..c275f66 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_selected.imageset/home_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/Contents.json new file mode 100644 index 0000000..142d759 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "home_unselected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/home_unselected.svg b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/home_unselected.svg new file mode 100644 index 0000000..c916715 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_home_unselected.imageset/home_unselected.svg @@ -0,0 +1,3 @@ + + + diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/Contents.json new file mode 100644 index 0000000..6e8308a --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "location_selected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/location_selected.svg b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/location_selected.svg new file mode 100644 index 0000000..80a8e30 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_selected.imageset/location_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/Contents.json new file mode 100644 index 0000000..df30698 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "location_unselected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/location_unselected.svg b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/location_unselected.svg new file mode 100644 index 0000000..8079394 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_location_unselected.imageset/location_unselected.svg @@ -0,0 +1,3 @@ + + + diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/Contents.json new file mode 100644 index 0000000..33073db --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "person_selected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/person_selected.svg b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/person_selected.svg new file mode 100644 index 0000000..a33fedf --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_selected.imageset/person_selected.svg @@ -0,0 +1,3 @@ + + + diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/Contents.json b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/Contents.json new file mode 100644 index 0000000..8ad8aa9 --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "person_unselected.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/person_unselected.svg b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/person_unselected.svg new file mode 100644 index 0000000..65c366c --- /dev/null +++ b/MatzipBook/MatzipBook/Core/DesignSystem/Resources/Assets.xcassets/Icons/ic_person_unselected.imageset/person_unselected.svg @@ -0,0 +1,3 @@ + + + diff --git a/MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift b/MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift new file mode 100644 index 0000000..91d3271 --- /dev/null +++ b/MatzipBook/MatzipBook/Presentation/Bookmark/BookmarkViewController.swift @@ -0,0 +1,17 @@ +// +// BookmarkViewController.swift +// MatzipBook +// +// Created by RAFA on 5/30/25. +// + +import UIKit + +class BookmarkViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.mainBackgroundColor + } +} diff --git a/MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift b/MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift new file mode 100644 index 0000000..be8ae2f --- /dev/null +++ b/MatzipBook/MatzipBook/Presentation/Home/HomeViewController.swift @@ -0,0 +1,17 @@ +// +// HomeViewController.swift +// MatzipBook +// +// Created by RAFA on 5/30/25. +// + +import UIKit + +class HomeViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.mainBackgroundColor + } +} diff --git a/MatzipBook/MatzipBook/Presentation/Main/MainTab.swift b/MatzipBook/MatzipBook/Presentation/Main/MainTab.swift new file mode 100644 index 0000000..7ce6e6a --- /dev/null +++ b/MatzipBook/MatzipBook/Presentation/Main/MainTab.swift @@ -0,0 +1,39 @@ +// +// MainTab.swift +// MatzipBook +// +// Created by RAFA on 5/30/25. +// + +import UIKit + +enum MainTab: Int, CaseIterable { + case home, location, bookmark, profile + + var icon: UIImage? { + switch self { + case .home: return .icHomeUnselected + case .location: return .icLocationUnselected + case .bookmark: return .icBookmarkUnselected + case .profile: return .icPersonUnselected + } + } + + var selectedIcon: UIImage? { + switch self { + case .home: return .icHomeSelected + case .location: return .icLocationSelected + case .bookmark: return .icBookmarkSelected + case .profile: return .icPersonSelected + } + } + + var viewController: UIViewController { + switch self { + case .home: return UINavigationController(rootViewController: HomeViewController()) + case .location: return UINavigationController(rootViewController: MapViewController()) + case .bookmark: return UINavigationController(rootViewController: BookmarkViewController()) + case .profile: return UINavigationController(rootViewController: ProfileViewController()) + } + } +} diff --git a/MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift b/MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift new file mode 100644 index 0000000..62bd767 --- /dev/null +++ b/MatzipBook/MatzipBook/Presentation/Main/MainTabBarController.swift @@ -0,0 +1,87 @@ +// +// MainTabBarController.swift +// MatzipBook +// +// Created by RAFA on 5/30/25. +// + +import UIKit + +final class MainTabBarController: UITabBarController { + + // MARK: - Properties + + private var customTabBarView: UIView = UIView(frame: .zero) + + // MARK: - Lifecycle + + override func viewDidLoad() { + super.viewDidLoad() + + setupViewControllers() + configureTabBarView() + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + setupTabBarFrame() + } + + // MARK: - UI + + private func setupTabBarFrame() { + let height: CGFloat = view.safeAreaInsets.bottom + 68 + var frame: CGRect = tabBar.frame + frame.size.height = height + frame.origin.y = view.frame.size.height - height + + tabBar.frame = frame + tabBar.setNeedsLayout() + tabBar.layoutIfNeeded() + + customTabBarView.frame = tabBar.frame + } + + private func setupViewControllers() { + viewControllers = MainTab.allCases.map { tab in + let viewController: UIViewController = tab.viewController + viewController.tabBarItem = UITabBarItem( + title: nil, + image: tab.icon?.withRenderingMode(.alwaysOriginal), + selectedImage: tab.selectedIcon?.withRenderingMode(.alwaysOriginal) + ) + + viewController.tabBarItem.imageInsets = UIEdgeInsets( + top: 5, + left: 0, + bottom: -5, + right: 0 + ) + + return viewController + } + } + + private func configureTabBarView() { + customTabBarView.frame = tabBar.frame + customTabBarView.backgroundColor = UIColor.mainBackgroundColor + customTabBarView.layer.masksToBounds = false + customTabBarView.layer.cornerRadius = 24 + customTabBarView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + customTabBarView.layer.shadowColor = UIColor.shadowColor.cgColor + customTabBarView.layer.shadowOffset = CGSize(width: 0, height: 0) + customTabBarView.layer.shadowOpacity = 1 + customTabBarView.layer.shadowRadius = 10 + + DispatchQueue.main.async { + self.customTabBarView.layer.shadowPath = UIBezierPath( + roundedRect: self.customTabBarView.bounds, + cornerRadius: 24 + ).cgPath + } + + view.addSubview(customTabBarView) + view.bringSubviewToFront(tabBar) + } +} diff --git a/MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift b/MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift new file mode 100644 index 0000000..cee6862 --- /dev/null +++ b/MatzipBook/MatzipBook/Presentation/Map/MapViewController.swift @@ -0,0 +1,17 @@ +// +// MapViewController.swift +// MatzipBook +// +// Created by RAFA on 5/30/25. +// + +import UIKit + +class MapViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.mainBackgroundColor + } +} diff --git a/MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift b/MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift new file mode 100644 index 0000000..f597b02 --- /dev/null +++ b/MatzipBook/MatzipBook/Presentation/Profile/ProfileViewController.swift @@ -0,0 +1,17 @@ +// +// ProfileViewController.swift +// MatzipBook +// +// Created by RAFA on 5/30/25. +// + +import UIKit + +class ProfileViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = UIColor.mainBackgroundColor + } +} diff --git a/MatzipBook/MatzipBook/Presentation/ViewController.swift b/MatzipBook/MatzipBook/Presentation/ViewController.swift deleted file mode 100644 index 1bdd224..0000000 --- a/MatzipBook/MatzipBook/Presentation/ViewController.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ViewController.swift -// MatzipBook -// -// Created by RAFA on 3/27/25. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/MatzipBook/Podfile b/MatzipBook/Podfile index a40b860..308983e 100644 --- a/MatzipBook/Podfile +++ b/MatzipBook/Podfile @@ -1,11 +1,16 @@ -# Uncomment the next line to define a global platform for your project -# platform :ios, '9.0' +platform :ios, '16.0' target 'MatzipBook' do - # Comment the next line if you don't want to use dynamic frameworks use_frameworks! # Pods for MatzipBook pod 'SwiftLint' + post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.0' + end + end + end end diff --git a/MatzipBook/Podfile.lock b/MatzipBook/Podfile.lock index 1fe639f..cb4c9f3 100644 --- a/MatzipBook/Podfile.lock +++ b/MatzipBook/Podfile.lock @@ -11,6 +11,6 @@ SPEC REPOS: SPEC CHECKSUMS: SwiftLint: 3d48e2fb2a3468fdaccf049e5e755df22fb40c2c -PODFILE CHECKSUM: 19f42d0b88906baf5d454425a4281a9a2ed4835d +PODFILE CHECKSUM: 2654d5e3e6997c854ff1671419d73ca19518ac76 COCOAPODS: 1.16.2