create toast stack

This commit is contained in:
desp0o
2025-04-18 20:04:16 +04:00
parent 2dce58bfb1
commit f3e2940e00
6 changed files with 114 additions and 3 deletions
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>ToastKit.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>
+5 -3
View File
@@ -32,6 +32,7 @@ public struct CustomToast: View {
let innerVpadding: CGFloat
let outterHpadding: CGFloat
let stackAligment: Alignment
let isStackMaxHeight: Bool
let cornerRadius: CGFloat
@@ -83,6 +84,7 @@ public struct CustomToast: View {
innerVpadding: CGFloat = 10,
outterHpadding: CGFloat = 20,
stackAligment: Alignment = .top,
isStackMaxHeight: Bool = true,
cornerRadius: CGFloat = 12,
@@ -132,6 +134,7 @@ public struct CustomToast: View {
self.innerVpadding = innerVpadding
self.outterHpadding = outterHpadding
self.stackAligment = stackAligment
self.isStackMaxHeight = isStackMaxHeight
self.cornerRadius = cornerRadius
@@ -232,7 +235,8 @@ public struct CustomToast: View {
.padding(.horizontal, outterHpadding)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: stackAligment)
.frame(maxWidth: .infinity, alignment: stackAligment)
.if(isStackMaxHeight) { $0.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: stackAligment)}
.onChange(of: isVisible) { _, newValue in
if newValue {
if autoDisappear {
@@ -261,5 +265,3 @@ public struct CustomToast: View {
}
}
}
@@ -0,0 +1,47 @@
//
// ToastStackManager.swift
// ToastKit
//
// Created by Despo on 18.04.25.
//
import SwiftUI
@available(macOS 14.0, *)
@available(iOS 17, *)
struct ToastItemModel: Identifiable, Equatable {
let id = UUID()
let title: String
let toastColor: ToastColorTypes
let autoDisappearDuration: TimeInterval
let isStackMaxHeight: Bool = false
static func == (lhs: ToastItemModel, rhs: ToastItemModel) -> Bool {
return lhs.id == rhs.id
}
}
@available(macOS 14.0, *)
@available(iOS 17, *)
@MainActor
class ToastStackManager: ObservableObject {
@Published var toasts: [ToastItemModel] = []
func show(title: String, toastColor: ToastColorTypes, autoDisappearDuration: TimeInterval = 2.0) {
let toast = ToastItemModel(
title: title,
toastColor: toastColor,
autoDisappearDuration: autoDisappearDuration
)
toasts.insert(toast, at: 0)
DispatchQueue.main.asyncAfter(deadline: .now() + autoDisappearDuration) { [weak self] in
self?.removeToast(toast)
}
}
private func removeToast(_ toast: ToastItemModel) {
toasts.removeAll { $0.id == toast.id }
}
}
@@ -0,0 +1,41 @@
//
// ToastStackView.swift
// ToastKit
//
// Created by Despo on 18.04.25.
//
import SwiftUI
@available(macOS 14.0, *)
@available(iOS 17, *)
struct ToastStackView: View {
@StateObject var vm: ToastStackManager
let transitionType: AnyTransition
init(
vm: ToastStackManager,
transitionType: AnyTransition = .move(edge: .top).combined(with: .opacity)
) {
_vm = StateObject(wrappedValue: vm)
self.transitionType = transitionType
}
var body: some View {
VStack {
ForEach(vm.toasts, id: \.id) { toast in
ZStack {
CustomToast(
isVisible: .constant(true),
title: toast.title,
toastColor: toast.toastColor,
isStackMaxHeight: toast.isStackMaxHeight
)
}
.transition(transitionType)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity,alignment: .top)
.animation(.bouncy, value: vm.toasts)
}
}