mirror of
https://github.com/Desp0o/ToastKit.git
synced 2026-06-17 14:34:30 +00:00
create toast stack
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
Generated
BIN
Binary file not shown.
@@ -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>
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user