exyte / PopupView

Toasts and popups library written with SwiftUI
MIT License
3.44k stars 268 forks source link

how to pass custom Text to pop up #54

Closed beks6 closed 2 years ago

beks6 commented 2 years ago

Hey all, I have Button which calls a ScannerView and receives the scanned barcode. I would like to pass the scanned String to a popup view and can't figure out how to do it properly. The pop up is always empty

That's my simplified code

struct WorkflowView: View {

    @State private var isShowingScanner = false
    @State private var scannedCode: String?
    @State private var isShowingScannerBanner = false

    var body: some View {
        ZStack{ //need to trigger pop up views
            VStack {
                    Button(action: {
                        self.isShowingScanner = true
                    }, label: {
                        Text("Scan barcode")
                            .font(.title)
                            .padding(5)
                            .background(Color.orange)
                            .cornerRadius(10)
                    })
            }
            .sheet(isPresented: $isShowingScanner) {
                    CodeScannerView(codeTypes: [.ean8, .ean13, .upce, .code39, .code93, .code128, .code39Mod43, .interleaved2of5, .qr]) { response in
                        if case let .success(result) = response {
                            scannedCode = result.string
                            isShowingScanner = false
                            isShowingScannerBanner = true
                        }
                    }
                }
        }
        .popup(isPresented: $isShowingScannerBanner, type: .floater(verticalPadding: 90), position: .top, autohideIn: 2) {
                    createSuccessBanner(message: scannedCode ?? "")
                }
}
f3dm76 commented 2 years ago

Hello @beks6, your code doesn't show if your CodeScannerView works and actually updates scannedCode value. Also doesn't show how createSuccessBanner works - might be losing your value there. But if both of them work as expected, the code basically looks something like this:

struct ContentView: View {

    @State private var scannedCode: String?
    @State private var isShowingScannerBanner = false

    var body: some View {
            VStack {
                Button {
                    self.scannedCode = "\(Double.random(in: 0...100))"
                    isShowingScannerBanner = true
                } label: {
                    Text("Scan barcode")
                        .font(.title)
                        .padding(5)
                        .background(Color.orange)
                        .cornerRadius(10)
                }
            }
        .popup(isPresented: $isShowingScannerBanner, type: .floater(verticalPadding: 90), position: .top, autohideIn: 2) {
            Text("\(scannedCode ?? "")")
        }
    }
}

This code updates content successfully, please check it out. If you have any further questions please provide minimal reproducible example. Also please make sure you are using the latest versions of xcode, ios and popup library. Have a nice day!

beks6 commented 2 years ago

ok, this is a bit weird (or even known??)

If I add a

Text("\(scannedCode ?? "")")

anywhere in my VStack it works fine. So I have now to use the .hidden() function on that Text.

To me it looks like, if the variable doesn't get "consumed" it gets lost somewhere

I had this Text earlier, so I was sure the Scanner works fine and returns the scanned value. But I wanted to update some info tasks with such popups, so I removed the Text and wasn't aware, that this caused the issue.

Thank you for your fast response. I really don't know if this is a wanted behaviour by Apple or a bug or even my code is a bit buggy?

To your question

createSuccessBanner just holds a Text with size and color to represent the message

func createSuccessBanner(message: String?) -> some View {

    GeometryReader { (deviceSize: GeometryProxy) in
        VStack {
            Text("Folder \(message ?? "") created")
                .frame(width: deviceSize.size.width*0.93, height: 70)
                .background(Color.green)
                .cornerRadius(10.0)
        }
    }
}
antonioreyna commented 1 year ago

hello i have a similar issue,

@State private var loadingTitle: String? = nil
    @State private var loadingMessage: String? = nil

then on a button click i do:

self.loadingTitle = "title"
self.loadingMessage = "message."
showLoading = true

And mi popup looks like this but the texts are empty, just the "ok" fixed one appears.

.popup(isPresented: $showLoading) {
                VStack {
                    //Text("ok")
                    Text("\(loadingTitle ?? "")")
                        //.frame(maxWidth: .infinity)
                    //Text("\(loadingMessage ?? "")")
                }
                .padding(20)
                .background(Color.white)
                .cornerRadius(4)
                .shadow(color: .black.opacity(0.2), radius: 4, x: 0, y: 1)
                .padding(20)
            } customize: {
                $0
                    .animation(.spring())
                    .closeOnTap(false)
                    .closeOnTapOutside(false)
                    .dragToDismiss(false)
                    .isOpaque(true)
                    .backgroundColor(.white.opacity(0.5))
            }