From 86b2ff30f29b9b18de9afe9e6e2946f39f35b2bb Mon Sep 17 00:00:00 2001 From: devminseok Date: Sat, 17 Aug 2024 01:12:57 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feature:=20toast=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Component/ToastDetailView.swift | 30 ++++++++ .../Example/Sources/ContentView.swift | 8 ++- .../Sources/Component/Toast/Toast.swift | 30 ++++++++ .../Component/Toast/ToastViewModifier.swift | 69 +++++++++++++++++++ 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 Projects/Shared/DesignSystem/Example/Sources/Component/ToastDetailView.swift create mode 100644 Projects/Shared/DesignSystem/Sources/Component/Toast/Toast.swift create mode 100644 Projects/Shared/DesignSystem/Sources/Component/Toast/ToastViewModifier.swift diff --git a/Projects/Shared/DesignSystem/Example/Sources/Component/ToastDetailView.swift b/Projects/Shared/DesignSystem/Example/Sources/Component/ToastDetailView.swift new file mode 100644 index 0000000..ed9200b --- /dev/null +++ b/Projects/Shared/DesignSystem/Example/Sources/Component/ToastDetailView.swift @@ -0,0 +1,30 @@ +// +// ToastDetailView.swift +// DesignSystemExample +// +// Created by devMinseok on 8/16/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +import DesignSystem + +struct ToastDetailView: View { + @State var toast: DefaultToast? + + var body: some View { + VStack { + Button { + toast = DefaultToast(message: "Thist is test message for toast", image: Image(systemName: "left")) + } label: { + Text("showToast") + } + } + .toastDestination(toast: $toast) + } +} + +#Preview { + ToastDetailView() +} diff --git a/Projects/Shared/DesignSystem/Example/Sources/ContentView.swift b/Projects/Shared/DesignSystem/Example/Sources/ContentView.swift index a41de69..6f44c93 100644 --- a/Projects/Shared/DesignSystem/Example/Sources/ContentView.swift +++ b/Projects/Shared/DesignSystem/Example/Sources/ContentView.swift @@ -60,6 +60,12 @@ struct ContentView: View { Text("BottomSheet") } + NavigationLink { + ToastDetailView() + } label: { + Text("Toast") + } + NavigationLink { } label: { @@ -69,7 +75,7 @@ struct ContentView: View { NavigationLink { } label: { - Text("Toast") + Text("TextField") } } } diff --git a/Projects/Shared/DesignSystem/Sources/Component/Toast/Toast.swift b/Projects/Shared/DesignSystem/Sources/Component/Toast/Toast.swift new file mode 100644 index 0000000..b6babae --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Toast/Toast.swift @@ -0,0 +1,30 @@ +// +// Toast.swift +// DesignSystem +// +// Created by devMinseok on 8/16/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +public protocol Toast: Equatable { + var message: String { get } + var image: Image? { get } + var hideAutomatically: Bool { get } +} + +public struct DefaultToast: Toast { + public let message: String + public let image: Image? + public let hideAutomatically: Bool + + public init( + message: String, + image: Image + ) { + self.message = message + self.image = image + hideAutomatically = true + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Component/Toast/ToastViewModifier.swift b/Projects/Shared/DesignSystem/Sources/Component/Toast/ToastViewModifier.swift new file mode 100644 index 0000000..5bb91c4 --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Toast/ToastViewModifier.swift @@ -0,0 +1,69 @@ +// +// ToastView.swift +// DesignSystem +// +// Created by devMinseok on 8/16/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +public struct ToastViewModifier: ViewModifier { + @Binding var toast: T? + + public init(toast: Binding) { + _toast = toast + } + + public func body(content: Content) -> some View { + ZStack(alignment: .bottom ) { + content + .frame(maxWidth: .infinity, maxHeight: .infinity) + + if let toast { + HStack(alignment: .center, spacing: 8) { + if let image = toast.image { + image + } + Text(toast.message) + .foregroundStyle(Global.Color.white) + .font(Typography.subBodyR) + .multilineTextAlignment(.leading) + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding(16) + .background( + RoundedRectangle(cornerRadius: 16) + .fill(Alias.Color.Background.inverse) + .opacity(Global.Opacity._90d) + ) + .padding(.horizontal, Global.Dimension._20f) + .transition( + .move(edge: .bottom) + .combined(with: .opacity.animation(.easeInOut)) + ) + .onAppear { + if toast.hideAutomatically { + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + if self.toast != nil { + self.toast = nil + } + } + } + } + .onTapGesture { + self.toast = nil + } + } + } + .animation(.spring(duration: 0.3), value: self.toast) + } +} + +extension View { + public func toastDestination( + toast: Binding + ) -> some View { + self.modifier(ToastViewModifier(toast: toast)) + } +} From 00a9651c627128f307425f90b1bb121e43a4a32b Mon Sep 17 00:00:00 2001 From: devminseok Date: Sat, 17 Aug 2024 01:43:07 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20BottomSheet=20ViewModifier=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...et.swift => BottomSheetViewModifier.swift} | 43 ++++++++++++------- .../Component/Toast/ToastViewModifier.swift | 10 +++-- 2 files changed, 33 insertions(+), 20 deletions(-) rename Projects/Shared/DesignSystem/Sources/Component/BottomSheet/{BottomSheet.swift => BottomSheetViewModifier.swift} (73%) diff --git a/Projects/Shared/DesignSystem/Sources/Component/BottomSheet/BottomSheet.swift b/Projects/Shared/DesignSystem/Sources/Component/BottomSheet/BottomSheetViewModifier.swift similarity index 73% rename from Projects/Shared/DesignSystem/Sources/Component/BottomSheet/BottomSheet.swift rename to Projects/Shared/DesignSystem/Sources/Component/BottomSheet/BottomSheetViewModifier.swift index 7ed52a5..950bbed 100644 --- a/Projects/Shared/DesignSystem/Sources/Component/BottomSheet/BottomSheet.swift +++ b/Projects/Shared/DesignSystem/Sources/Component/BottomSheet/BottomSheetViewModifier.swift @@ -8,23 +8,24 @@ import SwiftUI -extension View { - public func bottomSheet< - Item: Identifiable, - Content: View - >( - item: Binding, - @ViewBuilder content: @escaping (Item) -> Content - ) -> some View { +struct BottomSheetViewModifier< + Item: Identifiable, + BottomSheetContent: View +>: ViewModifier { + @Binding var item: Item? + let bottomSheetContent: (Item) -> BottomSheetContent + + func body(content: Content) -> some View { ZStack(alignment: .bottom) { - self + content + .frame(maxWidth: .infinity, maxHeight: .infinity) .zIndex(1) - if let wrappedItem = item.wrappedValue { + if let item { Global.Color.black.opacity(Global.Opacity._50d) .ignoresSafeArea() .onTapGesture { - item.wrappedValue = nil + self.item = nil } .transition( .opacity.animation(.easeInOut) @@ -44,14 +45,12 @@ extension View { DragGesture(minimumDistance: 20) .onEnded { value in if value.translation.height > 100 { - withAnimation { - item.wrappedValue = nil - } + self.item = nil } } ) - content(wrappedItem) + bottomSheetContent(item) .frame(maxWidth: .infinity) .fixedSize(horizontal: false, vertical: true) .background(Global.Color.white) @@ -59,9 +58,21 @@ extension View { .frame(maxWidth: .infinity) .frame(maxHeight: UIScreen.main.bounds.height * 0.9, alignment: .bottom) .transition(.move(edge: .bottom)) - .animation(.spring(duration: 0.4)) .zIndex(3) } } + .animation(.spring(duration: 0.4), value: self.item == nil) + } +} + +extension View { + public func bottomSheet< + Item: Identifiable, + Content: View + >( + item: Binding, + @ViewBuilder content: @escaping (Item) -> Content + ) -> some View { + return self.modifier(BottomSheetViewModifier(item: item, bottomSheetContent: content)) } } diff --git a/Projects/Shared/DesignSystem/Sources/Component/Toast/ToastViewModifier.swift b/Projects/Shared/DesignSystem/Sources/Component/Toast/ToastViewModifier.swift index 5bb91c4..9ed6ba7 100644 --- a/Projects/Shared/DesignSystem/Sources/Component/Toast/ToastViewModifier.swift +++ b/Projects/Shared/DesignSystem/Sources/Component/Toast/ToastViewModifier.swift @@ -8,17 +8,18 @@ import SwiftUI -public struct ToastViewModifier: ViewModifier { +struct ToastViewModifier: ViewModifier { @Binding var toast: T? - public init(toast: Binding) { + init(toast: Binding) { _toast = toast } - public func body(content: Content) -> some View { + func body(content: Content) -> some View { ZStack(alignment: .bottom ) { content .frame(maxWidth: .infinity, maxHeight: .infinity) + .zIndex(1) if let toast { HStack(alignment: .center, spacing: 8) { @@ -45,7 +46,7 @@ public struct ToastViewModifier: ViewModifier { .onAppear { if toast.hideAutomatically { DispatchQueue.main.asyncAfter(deadline: .now() + 2) { - if self.toast != nil { + if self.toast != nil { self.toast = nil } } @@ -54,6 +55,7 @@ public struct ToastViewModifier: ViewModifier { .onTapGesture { self.toast = nil } + .zIndex(2) } } .animation(.spring(duration: 0.3), value: self.toast)