diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/100.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/100.png deleted file mode 100644 index bcba152..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/100.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/1024.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/1024.png deleted file mode 100644 index 9132a92..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/1024.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/114.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/114.png deleted file mode 100644 index ead6fd5..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/114.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/120.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/120.png deleted file mode 100644 index b9b6806..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/120.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/144.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/144.png deleted file mode 100644 index d672fb2..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/144.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/152.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/152.png deleted file mode 100644 index 293c4a1..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/152.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/167.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/167.png deleted file mode 100644 index c68f73a..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/167.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/180.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/180.png deleted file mode 100644 index 6cc0513..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/180.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/20.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/20.png deleted file mode 100644 index 9c10efa..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/20.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/29.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/29.png deleted file mode 100644 index 8fec360..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/29.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/40.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/40.png deleted file mode 100644 index 30f9449..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/40.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/50.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/50.png deleted file mode 100644 index 7272f9b..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/50.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/57.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/57.png deleted file mode 100644 index 37ced47..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/57.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/58.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/58.png deleted file mode 100644 index a66a51b..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/58.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/60.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/60.png deleted file mode 100644 index 634395f..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/60.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/72.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/72.png deleted file mode 100644 index 0b1ff4c..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/72.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/76.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/76.png deleted file mode 100644 index e4fcb32..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/76.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/80.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/80.png deleted file mode 100644 index 42f7580..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/80.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/87.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/87.png deleted file mode 100644 index 9eb036e..0000000 Binary files a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/87.png and /dev/null differ diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/Contents.json b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/Contents.json index 4fdf882..f1a93eb 100644 --- a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,153 +1,9 @@ { "images" : [ { - "filename" : "40.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "filename" : "60.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "filename" : "29.png", - "idiom" : "iphone", - "scale" : "1x", - "size" : "29x29" - }, - { - "filename" : "58.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "87.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "filename" : "80.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "120.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "filename" : "57.png", - "idiom" : "iphone", - "scale" : "1x", - "size" : "57x57" - }, - { - "filename" : "114.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "57x57" - }, - { - "filename" : "120.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "filename" : "180.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "filename" : "20.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "filename" : "40.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "filename" : "29.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "filename" : "58.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "40.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "filename" : "80.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "50.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "50x50" - }, - { - "filename" : "100.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "50x50" - }, - { - "filename" : "72.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "72x72" - }, - { - "filename" : "144.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "72x72" - }, - { - "filename" : "76.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "filename" : "152.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "filename" : "167.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "filename" : "1024.png", - "idiom" : "ios-marketing", - "scale" : "1x", + "filename" : "Logo.png", + "idiom" : "universal", + "platform" : "ios", "size" : "1024x1024" } ], diff --git a/AsyncSwift/Assets.xcassets/AppIcon.appiconset/Logo.png b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/Logo.png new file mode 100644 index 0000000..c3dfabf Binary files /dev/null and b/AsyncSwift/Assets.xcassets/AppIcon.appiconset/Logo.png differ diff --git a/AsyncSwift/Models/Stamp.swift b/AsyncSwift/Models/Stamp.swift index 4e6873c..d04ab22 100644 --- a/AsyncSwift/Models/Stamp.swift +++ b/AsyncSwift/Models/Stamp.swift @@ -12,7 +12,8 @@ struct Stamp: Decodable { } struct Card { + var originalPosition: CGFloat - var isSelected = false var image: Image + var event: String } diff --git a/AsyncSwift/Observed/StampView+Observed.swift b/AsyncSwift/Observed/StampView+Observed.swift index 1ffc1bd..aa7229a 100644 --- a/AsyncSwift/Observed/StampView+Observed.swift +++ b/AsyncSwift/Observed/StampView+Observed.swift @@ -9,9 +9,10 @@ import SwiftUI extension StampView { @MainActor final class Observed: ObservableObject { - @Published var cards = [String: Card]() + @Published var cards: [Card] = [] @Published var events = [String]() @Published var currentIndex = 0 + @Published var isLoading = true private let keyChainManager = KeyChainManager() private let cardInterval: CGFloat = (UIScreen.main.bounds.width - 32) * 56 / 358 private let cardSize: CGFloat = UIScreen.main.bounds.width - 32 @@ -22,8 +23,7 @@ extension StampView { private func getEvents() -> [String] { let pwRaw = keyChainManager.getItem(key: keyChainManager.stampKey) as? String - guard var convertedStringArray = pwRaw?.convertToStringArray() else { return [] } - convertedStringArray.insert("Next", at: 0) // MARK: Test 실제에서는 Next storage 둘다 설정해야함 + guard let convertedStringArray = pwRaw?.convertToStringArray() else { return [] } self.events = convertedStringArray.reversed() return events } @@ -33,27 +33,33 @@ extension StampView { private func fetchStampsImages(){ let events = getEvents() + guard !events.isEmpty else { + isLoading = false + return + } + events.enumerated().forEach { [weak self] in - guard let self = self else { return } + guard let self else { return } let event = $0.element let index = $0.offset Task { @MainActor () -> Void in guard let cardImageURL = URL(string: "https://raw.githubusercontent.com/Async-Swift/jsonstorage/main/Images/Stamp/" + event + "/stamp.png") else { return } - + let cardImageRequest = URLRequest(url: cardImageURL) let (cardImageData, cardImageResponse) = try await URLSession.shared.data(for: cardImageRequest) guard let httpsResponse = cardImageResponse as? HTTPURLResponse, httpsResponse.statusCode == 200 else { return } - + guard let cardUIImage = UIImage(data: cardImageData) else { return } - - self.cards[event] = Card(originalPosition: cardInterval * CGFloat(index), - image: Image(uiImage: cardUIImage)) - // 가장 최근의 EventCard가 선택된 상태로 지정하기 - if index == 0 { - self.cards[event]?.isSelected = true - } else { - self.cards[event]?.isSelected = false + + let card = Card( + originalPosition: self.cardInterval * CGFloat(index), + image: Image(uiImage: cardUIImage), + event: event + ) + self.cards.append(card) + if index == events.count - 1 { + self.isLoading = false } } } @@ -105,40 +111,5 @@ extension StampView { return stamp } - - /// 가장 맨 위에 올라온 카드라면 아무것도 작동안하도록, 아니라면 가장 맨위로 올도록 하는 함수입니다. - func didCardTapped(index: Int, scrollReader: ScrollViewProxy) { - if index != currentIndex { - scrollReader.scrollTo(0, anchor: .init(x: 0, y: 94)) - withAnimation(.spring()) { - cards[events[index]]?.isSelected = true - cards[events[currentIndex]]?.isSelected = false - currentIndex = index - } - } - } - - /// 카드의 개수에 따라서 카드의 위치를 지정해주는 함수입니다. - func getCardOffsetY(index: Int, size: CGSize) -> CGFloat { - withAnimation(.spring()) { - guard let card = cards[events[index]] else { return .zero} - if card.isSelected { - return .zero - } else if size.height - CGFloat(94) < cardSize + CGFloat(16) + cardInterval * CGFloat(cards.count - 1) { - return cardSize + CGFloat(16) + card.originalPosition - } else { - return size.height - CGFloat(94) - cardInterval * CGFloat(cards.count - index) - CGFloat(8) - } - } - } - - /// 스크롤을 원할하게 하기 위해서 Offset 으로 원래 크기 보다 밀려난 만큼 Spacer로 확보해줍니다. - func getSpacerMinLength(size: CGSize) -> CGFloat { - if size.height - CGFloat(94) < cardSize + CGFloat(16) + cardInterval * CGFloat(cards.count - 1) { - return cardSize + CGFloat(16) + cardInterval * CGFloat(cards.count - 1) + cardSize - } else { - return size.height - CGFloat(94) - cardInterval - } - } } } diff --git a/AsyncSwift/Views/StampView.swift b/AsyncSwift/Views/StampView.swift index 232c2e8..6777dd8 100644 --- a/AsyncSwift/Views/StampView.swift +++ b/AsyncSwift/Views/StampView.swift @@ -10,41 +10,36 @@ import SwiftUI struct StampView: View { @StateObject var observed = Observed() @EnvironmentObject var envObserved: MainTabViewObserved + let columns = [ + GridItem(.flexible(), spacing: 10), + GridItem(.flexible()) + ] var body: some View { - GeometryReader { geometry in - if observed.cards.isEmpty { - emptyCardView - .padding(36) - } else { + + GeometryReader { proxy in + NavigationView { ScrollView(showsIndicators: false) { ScrollViewReader { reader in - HStack(alignment: .bottom) { - Text("Stamp") - .font(.system(size: 34)) - .fontWeight(.bold) - .padding(.leading, 16) - .padding(.bottom, 7) - .padding(.top, 48) - Spacer() - } - .frame(height: 94) - ZStack { - ForEach(0.. some View { - observed.cards[observed.events[index]]?.image + @ViewBuilder func cardView(card: Card, size: CGSize) -> some View { + card.image .resizable() - .aspectRatio(contentMode: .fit) + .aspectRatio(contentMode: .fill) .shadow(color: Color.black.opacity(0.1), radius: 10, y: 4) - .offset(y: observed.getCardOffsetY(index: index, size: size)) - .onTapGesture { - observed.didCardTapped(index: index, scrollReader: scrollReader) - } } }