These are all codes
PopupViewModifier.swift
struct PopupViewModifier<T: View>: ViewModifier {
let popup: T
var isPresented: Bool = false
var alignment: Alignment = .center
// 1.
init(isPresented: Bool, alignment: Alignment, @ViewBuilder content: () -> T) { // (*)
self.isPresented = isPresented
self.alignment = alignment // (*)
popup = content()
}
// 2.
func body(content: Content) -> some View {
content
.overlay(popupContent())
}
// 3.
@ViewBuilder private func popupContent() -> some View {
GeometryReader { geometry in
if isPresented {
popup
.animation(.spring()) // 1.
.transition(.scale)
.frame(width: geometry.size.width, height: geometry.size.height, alignment: alignment) // (*)
}
}
}
}
extension View {
func popup<T: View>(
isPresented: Bool,
alignment: Alignment = .center,
@ViewBuilder content: () -> T
) -> some View {
return modifier(PopupViewModifier(isPresented: isPresented,
alignment: alignment,
content: content))
}
}
LoadingView
struct LoadingView: View {
@EnvironmentObject var home: HomeGlobal
var body: some View {
Group {
ProgressView("Loading…")
.foregroundColor(.white)
.progressViewStyle(CircularProgressViewStyle(tint: .white))
}
.padding()
.background(Color.black.opacity(0.3))
.cornerRadius(home.cornerRadius)
}
}
SnackbarView.swift
struct SnackbarView: View {
@EnvironmentObject var home: HomeGlobal
var userAvator: String = "person.fill"
var userName: String = "Archi"
var message: String = "helllo"
var body: some View {
HStack() {
Image(systemName: userAvator )
.resizable()
.aspectRatio(contentMode: ContentMode.fill)
.frame(width: home.defaultPadding*3, height: home.defaultPadding*3)
VStack(alignment: .leading, spacing: 4) {
Text(userName)
.foregroundColor(.black)
.font(home.fontTitle3)
Text(message)
.font(home.fontBody)
.foregroundColor(.black)
}
}
.padding(home.defaultPadding)
.frame(maxWidth: .infinity, idealHeight: home.defaultNavHeight)
.background(Color.black.opacity(0.3))
}
}
ContentView.swift
struct ContentView: View {
@State var isPresented = false
var body: some View {
ZStack {
Color.green
VStack {
Spacer()
Button("Toggle", action: {
withAnimation {
isPresented.toggle()
}
})
}
}
.popup(isPresented: isPresented,
alignment: .top,
content: { SnackbarView() })
}
}