diff --git a/GAMSS/Info.plist b/GAMSS/Info.plist index f140dcc..c0fffca 100644 --- a/GAMSS/Info.plist +++ b/GAMSS/Info.plist @@ -8,6 +8,8 @@ $(BASE_URL) FIREBASE_CRASHLYTICS_COLLECTION_ENABLED NO + UIDesignRequiresCompatibility + UIAppFonts Pretendard-Regular.otf diff --git a/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/Contents.json b/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/Contents.json new file mode 100644 index 0000000..fcc9136 --- /dev/null +++ b/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tabIconChat@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tabIconChat@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "properties" : { + "template-rendering-intent" : "template" + }, + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/tabIconChat@2x.png b/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/tabIconChat@2x.png new file mode 100644 index 0000000..c67dd34 Binary files /dev/null and b/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/tabIconChat@2x.png differ diff --git a/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/tabIconChat@3x.png b/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/tabIconChat@3x.png new file mode 100644 index 0000000..dcb40cb Binary files /dev/null and b/GAMSS/Resources/Assets.xcassets/tabIconChat.imageset/tabIconChat@3x.png differ diff --git a/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/Contents.json b/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/Contents.json new file mode 100644 index 0000000..8a72727 --- /dev/null +++ b/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "tabIconHome@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "tabIconHome@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "properties" : { + "template-rendering-intent" : "template" + }, + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/tabIconHome@2x.png b/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/tabIconHome@2x.png new file mode 100644 index 0000000..0d8706a Binary files /dev/null and b/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/tabIconHome@2x.png differ diff --git a/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/tabIconHome@3x.png b/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/tabIconHome@3x.png new file mode 100644 index 0000000..c1d126f Binary files /dev/null and b/GAMSS/Resources/Assets.xcassets/tabIconHome.imageset/tabIconHome@3x.png differ diff --git a/GAMSS/Sources/Presentation/ConversationList/ConversationListView.swift b/GAMSS/Sources/Presentation/ConversationList/ConversationListView.swift index aad5327..02da55c 100644 --- a/GAMSS/Sources/Presentation/ConversationList/ConversationListView.swift +++ b/GAMSS/Sources/Presentation/ConversationList/ConversationListView.swift @@ -9,11 +9,9 @@ import SwiftUI struct ConversationListView: View { @StateObject private var viewModel: ConversationListViewModel - @Binding private var isTabBarHidden: Bool - init(viewModel: ConversationListViewModel, isTabBarHidden: Binding) { + init(viewModel: ConversationListViewModel) { _viewModel = StateObject(wrappedValue: viewModel) - _isTabBarHidden = isTabBarHidden } var body: some View { @@ -38,8 +36,7 @@ struct ConversationListView: View { conversationId: conversation.id ) ) - .onAppear { isTabBarHidden = true } - .onDisappear { isTabBarHidden = false } + .toolbar(.hidden, for: .tabBar) } } .task { @@ -60,7 +57,6 @@ struct ConversationListView: View { getConversationsUseCase: GetConversationsUseCase( conversationRepository: DefaultConversationRepository(networkManager: NetworkManager.shared) ) - ), - isTabBarHidden: .constant(false) + ) ) } diff --git a/GAMSS/Sources/Presentation/Home/HomeView.swift b/GAMSS/Sources/Presentation/Home/HomeView.swift index 2b85036..1c47ccc 100644 --- a/GAMSS/Sources/Presentation/Home/HomeView.swift +++ b/GAMSS/Sources/Presentation/Home/HomeView.swift @@ -10,11 +10,9 @@ import SwiftUI struct HomeView: View { @StateObject private var viewModel: HomeViewModel @FocusState private var isInputFocused: Bool - @Binding private var isTabBarHidden: Bool - init(viewModel: HomeViewModel, isTabBarHidden: Binding) { + init(viewModel: HomeViewModel) { _viewModel = StateObject(wrappedValue: viewModel) - _isTabBarHidden = isTabBarHidden } var body: some View { @@ -57,8 +55,7 @@ struct HomeView: View { initialSentMessage: viewModel.createdSentMessage ) ) - .onAppear { isTabBarHidden = true } - .onDisappear { isTabBarHidden = false } + .toolbar(.hidden, for: .tabBar) } } .alert(viewModel.alertMessage ?? "", isPresented: Binding( @@ -139,7 +136,6 @@ struct HomeView: View { sendMessageUseCase: SendMessageUseCase( conversationRepository: DefaultConversationRepository(networkManager: NetworkManager.shared) ) - ), - isTabBarHidden: .constant(false) + ) ) } diff --git a/GAMSS/Sources/Presentation/Root/CustomTabBar.swift b/GAMSS/Sources/Presentation/Root/CustomTabBar.swift deleted file mode 100644 index 3933755..0000000 --- a/GAMSS/Sources/Presentation/Root/CustomTabBar.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// CustomTabBar.swift -// GAMSS -// -// Created by cchanmi on 8/10/26. -// - -import SwiftUI - -struct CustomTabBar: View { - @Binding var selectedTab: MainTab - - var body: some View { - HStack(spacing: 0) { - ForEach(MainTab.allCases, id: \.self) { tab in - tabButton(for: tab) - } - } - .padding(.top, Spacing.spacing200) - .padding(.bottom, Spacing.spacing100) - .background(Color.colorWhite) - .overlay( - Rectangle() - .stroke(Color.colorBlack, lineWidth: 1.5) - ) - } - - @ViewBuilder - private func tabButton(for tab: MainTab) -> some View { - let isSelected = selectedTab == tab - - Button { - selectedTab = tab - } label: { - VStack(spacing: Spacing.spacing050) { - Image(tab.iconName) - .renderingMode(.template) - .resizable() - .scaledToFit() - .frame(width: 24, height: 24) - - Text(tab.title) - .typography(.caption3) - } - .foregroundStyle(isSelected ? Color.colorGray950 : Color.colorGray300) - .frame(maxWidth: .infinity) - } - .buttonStyle(.plain) - } -} - -#Preview { - VStack { - Spacer() - CustomTabBar(selectedTab: .constant(.home)) - .padding(.horizontal, Spacing.spacing400) - .padding(.bottom, Spacing.spacing200) - } -} diff --git a/GAMSS/Sources/Presentation/Root/MainTabView.swift b/GAMSS/Sources/Presentation/Root/MainTabView.swift index e9b09ce..a506232 100644 --- a/GAMSS/Sources/Presentation/Root/MainTabView.swift +++ b/GAMSS/Sources/Presentation/Root/MainTabView.swift @@ -9,48 +9,62 @@ import SwiftUI struct MainTabView: View { @State private var selectedTab: MainTab = .home - @State private var isTabBarHidden = false - var body: some View { - content - .safeAreaInset(edge: .bottom) { - if !isTabBarHidden { - CustomTabBar(selectedTab: $selectedTab) - .padding(.horizontal, Spacing.spacing400) - .padding(.bottom, Spacing.spacing200) - .transition(.opacity) - } - } - .animation(.easeInOut(duration: 0.15), value: isTabBarHidden) - } + init() { + let appearance = UITabBarAppearance() + let font = UIFont(name: FontWeight.medium.postScriptName(), size: Typography.caption3.metrics.fontSize) - @ViewBuilder - private var content: some View { - switch selectedTab { - case .archive: - ArchiveView() + appearance.configureWithOpaqueBackground() + appearance.backgroundColor = UIColor(Color.colorWhite) + + appearance.stackedLayoutAppearance.selected.iconColor = UIColor(Color.colorGray950) + appearance.stackedLayoutAppearance.selected.titleTextAttributes = [ + .foregroundColor: UIColor(Color.colorGray950), + .font: font as Any + ] + appearance.stackedLayoutAppearance.normal.iconColor = UIColor(Color.colorGray300) + appearance.stackedLayoutAppearance.normal.titleTextAttributes = [ + .foregroundColor: UIColor(Color.colorGray300), + .font: font as Any + ] + + UITabBar.appearance().standardAppearance = appearance + UITabBar.appearance().scrollEdgeAppearance = appearance + } - case .home: + var body: some View { + TabView(selection: $selectedTab) { HomeView( viewModel: HomeViewModel( sendMessageUseCase: SendMessageUseCase( conversationRepository: DefaultConversationRepository(networkManager: NetworkManager.shared) ) - ), - isTabBarHidden: $isTabBarHidden + ) ) + .tabItem { tabLabel(for: .home) } + .tag(MainTab.home) - case .chat: ConversationListView( viewModel: ConversationListViewModel( getConversationsUseCase: GetConversationsUseCase( conversationRepository: DefaultConversationRepository(networkManager: NetworkManager.shared) ) - ), - isTabBarHidden: $isTabBarHidden + ) ) + .tabItem { tabLabel(for: .chat) } + .tag(MainTab.chat) + + // 보관함 탭은 아직 노출하지 않음 — Figma 시안에서 당장 필요 없다고 확인됨. + // MainTab.archive case와 ArchiveView는 그대로 남겨두었으니, 실제 기능이 붙는 시점에 + // 여기 .tabItem을 추가하기만 하면 된다 (임의로 다시 추가하지 말 것). } } + + @ViewBuilder + private func tabLabel(for tab: MainTab) -> some View { + Image(tab.iconName).renderingMode(.template) + Text(tab.title) + } } #Preview {