ToastView.swift (2113B)
1 /* 2 * This file is part of GNU Taler 3 * (C) 2026 Bohdan, Volodymyr Potuzhnyi 4 * 5 * GNU Taler is free software; you can redistribute it and/or modify it under the 6 * terms of the GNU General Public License as published by the Free Software 7 * Foundation; either version 3, or (at your option) any later version. 8 * 9 * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 import SwiftUI 18 19 struct ToastModifier: ViewModifier { 20 @Binding var message: String? 21 let duration: TimeInterval 22 23 func body(content: Content) -> some View { 24 content.overlay(alignment: .bottom) { 25 if let message { 26 Text(message) 27 .font(.subheadline) 28 .fontWeight(.medium) 29 .foregroundColor(.posOnPrimaryContainer) 30 .padding(.horizontal, 20) 31 .padding(.vertical, 12) 32 .background(Color.posPrimaryContainer) 33 .clipShape(Capsule()) 34 .shadow(color: .black.opacity(0.15), radius: 4, y: 2) 35 .padding(.bottom, 24) 36 .transition(.move(edge: .bottom).combined(with: .opacity)) 37 .onAppear { 38 DispatchQueue.main.asyncAfter(deadline: .now() + duration) { 39 withAnimation(.easeOut(duration: 0.25)) { 40 self.message = nil 41 } 42 } 43 } 44 } 45 } 46 .animation(.easeInOut(duration: 0.25), value: message) 47 } 48 } 49 50 extension View { 51 func toast(message: Binding<String?>, duration: TimeInterval = 2.5) -> some View { 52 modifier(ToastModifier(message: message, duration: duration)) 53 } 54 }