From f716f83a83214e92dfbeccc9df168bd045bcc6a0 Mon Sep 17 00:00:00 2001 From: jim4020key Date: Fri, 30 Jun 2023 17:40:03 +0900 Subject: [PATCH] [Feat] #471 - Add ExploreShortcutViewModel --- .../HappyAnding.xcodeproj/project.pbxproj | 4 + .../ViewModel/ExploreShortcutViewModel.swift | 31 ++++ .../ExploreShortcutView.swift | 157 ++++++++---------- .../Views/TabView/ShortcutTabView.swift | 9 +- 4 files changed, 109 insertions(+), 92 deletions(-) create mode 100644 HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift diff --git a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj index 3cf164bb..ba2c1e4b 100644 --- a/HappyAnding/HappyAnding.xcodeproj/project.pbxproj +++ b/HappyAnding/HappyAnding.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 4D061BB82A47531800F76835 /* ExploreShortcutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D061BB72A47531800F76835 /* ExploreShortcutView.swift */; }; + 4D061BBA2A475EE800F76835 /* ExploreShortcutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */; }; 4D3DBB88292E67E600DE8160 /* EditNicknameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D3DBB87292E67E500DE8160 /* EditNicknameView.swift */; }; 4D3DBB962934E31A00DE8160 /* ShowProfileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D3DBB952934E31A00DE8160 /* ShowProfileView.swift */; }; 4D61A767291E1EE8000EF531 /* NavigationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */; }; @@ -187,6 +188,7 @@ 3D41EE06290A458B008BE986 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 3D41EE07290A4C18008BE986 /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; 4D061BB72A47531800F76835 /* ExploreShortcutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExploreShortcutView.swift; sourceTree = ""; }; + 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreShortcutViewModel.swift; sourceTree = ""; }; 4D3DBB87292E67E500DE8160 /* EditNicknameView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditNicknameView.swift; sourceTree = ""; }; 4D3DBB952934E31A00DE8160 /* ShowProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowProfileView.swift; sourceTree = ""; }; 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationViewModel.swift; sourceTree = ""; }; @@ -653,6 +655,7 @@ A0F822AB2910B8F100AF4448 /* ShortcutsZipViewModel.swift */, 4D61A766291E1EE8000EF531 /* NavigationViewModel.swift */, F9AC2BB52935201C00165820 /* CheckUpdateVersion.swift */, + 4D061BB92A475EE800F76835 /* ExploreShortcutViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -909,6 +912,7 @@ F9131B6B2922D38D00868A0E /* Keyword.swift in Sources */, F94B432E2907088400987819 /* UserCurationListView.swift in Sources */, A3FF0183291648A300384211 /* MailView.swift in Sources */, + 4D061BBA2A475EE800F76835 /* ExploreShortcutViewModel.swift in Sources */, A0F822AC2910B8F100AF4448 /* ShortcutsZipViewModel.swift in Sources */, 87276C382933F6AB00C92F4C /* CustomTextEditor.swift in Sources */, A34BF82D29AFC34F009BC946 /* AboutShortcutGradeView.swift in Sources */, diff --git a/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift new file mode 100644 index 00000000..8ae69669 --- /dev/null +++ b/HappyAnding/HappyAnding/ViewModel/ExploreShortcutViewModel.swift @@ -0,0 +1,31 @@ +// +// ExploreShortcutViewModel.swift +// HappyAnding +// +// Created by kimjimin on 2023/06/25. +// + +import SwiftUI + +final class ExploreShortcutViewModel: ObservableObject { + + var shortcutsZipViewModel = ShortcutsZipViewModel.share + + @Published private(set) var isCategoryCellViewFolded = true + @Published var isTappedAnnouncementCell = false + @Published private(set) var numberOfDisplayedCategories = 6 + @Published private(set) var randomCategories = Category.allCases.shuffled().prefix(2) + + func changeNumberOfCategories() { + isCategoryCellViewFolded.toggle() + numberOfDisplayedCategories = isCategoryCellViewFolded ? 6 : 12 + } + + func isShowingAnnouncement() { + isTappedAnnouncementCell = true + } + + func fetchShortcutsByCategories(category: Category) -> [Shortcuts] { + shortcutsZipViewModel.shortcutsInCategory[category.index] + } +} diff --git a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift index a5ff6dde..fa2d353b 100644 --- a/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift +++ b/HappyAnding/HappyAnding/Views/ExploreShortcutViews/ExploreShortcutView.swift @@ -9,83 +9,80 @@ import SwiftUI struct ExploreShortcutView: View { - @EnvironmentObject var shortcutsZipViewModel: ShortcutsZipViewModel + @StateObject var viewModel: ExploreShortcutViewModel // TODO: 추후 UpdateInfoView 제작 시 true로 변경해서 cell 보이게 하기 @AppStorage("isUpdateAnnnouncementShow") var isUpdateAnnnouncementShow: Bool = false - @Binding var isCategoryCellViewFolded: Bool - - @State var isTappedAnnouncementCell = false - @State private var numberOfDisplayedCategories = 6 - - let randomCategories: [Category] - var body: some View { - ScrollView { - VStack(spacing: 32) { - if isUpdateAnnnouncementShow { - Button { - isTappedAnnouncementCell = true - } label: { - AnnouncementCell(icon: "updateAppIcon", - tagName: TextLiteral.updateTag, - discription: TextLiteral.updateCellDescription, - isAnnouncementShow: $isUpdateAnnnouncementShow) - } - .id(000) - } - - sectionView(with: .recent) - .id(111) - - categoryCardView(with: randomCategories[0]) - - sectionView(with: .download) - - categoryCardView(with: randomCategories[1]) - - sectionView(with: .popular) - - VStack { - HStack { - SubtitleTextView(text: TextLiteral.categoryViewTitle) - - Spacer() - - Button(action: { - self.isCategoryCellViewFolded.toggle() - }, label: { - MoreCaptionTextView(text: isCategoryCellViewFolded ? TextLiteral.categoryViewUnfold : TextLiteral.categoryViewFold) - }) - .onChange(of: isCategoryCellViewFolded) { _ in - numberOfDisplayedCategories = isCategoryCellViewFolded ? 6 : 12 + ScrollViewReader { proxy in + ScrollView { + VStack(spacing: 32) { + if isUpdateAnnnouncementShow { + Button { + viewModel.isShowingAnnouncement() + } label: { + AnnouncementCell(icon: "updateAppIcon", + tagName: TextLiteral.updateTag, + discription: TextLiteral.updateCellDescription, + isAnnouncementShow: $isUpdateAnnnouncementShow) } + .id(000) } - .padding(.horizontal, 16) - LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) { - ForEach(Array(Category.allCases.enumerated()), id: \.offset) { index, value in + sectionView(with: .recent) + .id(111) + + categoryCardView(with: viewModel.randomCategories[0]) + + sectionView(with: .download) + + categoryCardView(with: viewModel.randomCategories[1]) + + sectionView(with: .popular) + + VStack { + HStack { + SubtitleTextView(text: TextLiteral.categoryViewTitle) - let data = NavigationListCategoryShortcutType(shortcuts: [], - categoryName: value, - navigationParentView: .shortcuts) + Spacer() - if index < numberOfDisplayedCategories { + Button { + viewModel.changeNumberOfCategories() + } label: { + MoreCaptionTextView(text: viewModel.isCategoryCellViewFolded ? TextLiteral.categoryViewUnfold : TextLiteral.categoryViewFold) + } + } + .padding(.horizontal, 16) + + LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) { + ForEach(Array(Category.allCases.enumerated()), id: \.offset) { index, value in - categoryCellView(with: value.translateName()) - .navigationLinkRouter(data: data) + let data = NavigationListCategoryShortcutType(shortcuts: [], + categoryName: value, + navigationParentView: .shortcuts) + if index < viewModel.numberOfDisplayedCategories { + + categoryCellView(with: value.translateName()) + .navigationLinkRouter(data: data) + + } } } + .padding(.horizontal, 16) + .padding(.bottom, 16) + .id(999) } - .padding(.horizontal, 16) - .padding(.bottom, 16) - .id(999) + } + .padding(.top, 20) + .padding(.bottom, 44) + } + .onChange(of: viewModel.isCategoryCellViewFolded) { _ in + withAnimation { + proxy.scrollTo(999, anchor: .bottom) } } - .padding(.top, 20) - .padding(.bottom, 44) } .scrollIndicators(.hidden) .navigationBarTitle(TextLiteral.exploreShortcutViewTitle) @@ -100,7 +97,7 @@ struct ExploreShortcutView: View { } } .navigationBarBackground ({ Color.shortcutsZipBackground }) - .sheet(isPresented: $isTappedAnnouncementCell) { + .sheet(isPresented: $viewModel.isTappedAnnouncementCell) { UpdateInfoView() .presentationDetents([.large]) .presentationDragIndicator(.visible) @@ -115,7 +112,7 @@ extension ExploreShortcutView { @ViewBuilder private func sectionView(with sectionType: SectionType) -> some View { - let shortcuts = sectionType.filterShortcuts(from: shortcutsZipViewModel) + let shortcuts = sectionType.filterShortcuts(from: viewModel.shortcutsZipViewModel) VStack(spacing: 0) { HStack { @@ -151,11 +148,11 @@ extension ExploreShortcutView { VStack(spacing: 0) { HStack { - + SubtitleTextView(text: category.translateName()) - + Spacer() - + MoreCaptionTextView(text: TextLiteral.more) .navigationLinkRouter(data: NavigationListCategoryShortcutType(shortcuts: [], categoryName: category, @@ -163,21 +160,19 @@ extension ExploreShortcutView { } .padding(.horizontal, 16) .padding(.bottom, 12) - + ScrollView(.horizontal, showsIndicators: false) { HStack { - ForEach(Array((shortcutsZipViewModel.shortcutsInCategory[randomCategories[0].index].enumerated())), id: \.offset) { index, shortcut in - if index < 7 { - let data = NavigationReadShortcutType( - shortcutID: shortcut.id, - navigationParentView: .shortcuts) - - ShortcutCardCell( - categoryShortcutIcon: shortcut.sfSymbol, - categoryShortcutName: shortcut.title, - categoryShortcutColor: shortcut.color) - .navigationLinkRouter(data: data) - } + ForEach(viewModel.fetchShortcutsByCategories(category: category).prefix(7), id: \.self) { shortcut in + let data = NavigationReadShortcutType( + shortcutID: shortcut.id, + navigationParentView: .shortcuts) + + ShortcutCardCell( + categoryShortcutIcon: shortcut.sfSymbol, + categoryShortcutName: shortcut.title, + categoryShortcutColor: shortcut.color) + .navigationLinkRouter(data: data) } } .padding(.horizontal, 16) @@ -200,9 +195,3 @@ extension ExploreShortcutView { } } -struct ExploreShortcutView_Previews: PreviewProvider { - static var previews: some View { - ExploreShortcutView(isCategoryCellViewFolded: .constant(true), randomCategories: [Category.lifestyle, Category.utility]) - } -} - diff --git a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift index db91ece5..4b17c112 100644 --- a/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift +++ b/HappyAnding/HappyAnding/Views/TabView/ShortcutTabView.swift @@ -27,8 +27,6 @@ struct ShortcutTabView: View { @State private var tempShortcutId = "" @State private var tempCurationId = "" - @State private var randomCategories = Category.allCases.shuffled().prefix(2) - @State var isFolded = true @State private var twiceTappedTab = 0 @State private var firstTabID = UUID() @@ -72,11 +70,6 @@ struct ShortcutTabView: View { } self.twiceTappedTab = 0 } - .onChange(of: isFolded) { _ in - withAnimation { - proxy.scrollTo(999, anchor: .bottom) - } - } .environmentObject(shortcutNavigation) .tabItem { Label("단축어", systemImage: "square.stack.3d.up.fill") @@ -113,7 +106,7 @@ struct ShortcutTabView: View { @ViewBuilder private func firstTab() -> some View { - ExploreShortcutView(isCategoryCellViewFolded: $isFolded, randomCategories: Array(randomCategories)) + ExploreShortcutView(viewModel: ExploreShortcutViewModel()) .modifierNavigation() .navigationBarBackground ({ Color.shortcutsZipBackground }) .id(firstTabID)