Home > AI > IOS > SwiftUI >

Popup component

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() })

    }
}

Leave a Reply