How to properly present PKPaymentAuthorizationViewController in a SwiftUI only project?
Asked Answered
A

1

5

I have visited this answer already and the present method proposed here doesn't work (anymore?). When I use a UIViewControllerRepresentable and then show it as a sheet it looks pretty awful:

Screenshot UIViewControllerRepresentable sheet

If I use overlay it looks exactly like I want it to looks but overlay cannot be triggered from a Button.

Here is the (condensed) code:

public struct ContentView: View {
    @ObservedObject var model: RootViewModel
    @State private var tappedDonate = false

    public var body: some View {
            Button(action: {
                tappedDonate = true
            }, label: {
                Text("Donate")
                    .frame(width: 300, height: 44, alignment: .center)
            })
            .frame(width: 300, height: 20, alignment: .center)
            .padding()
            .background(Color.black)
            .foregroundColor(.white)
            .cornerRadius(22)
            .sheet(isPresented: $tappedDonate) {
                ApplePayWrapper(request: model.buildApplePayment())
                    .background(Color.clear)
            }
    }

    public init(model: RootViewModel) {
        self.model = model
    }
}
Administration answered 29/6, 2020 at 12:41 Comment(2)
Did you find a better way to do this, even in SwiftUI 2? There's still no documentation or samples on this.Shropshire
Hi @Shropshire no I didn't, I have abandoned this project a bit because there are too many things happening in life at once at the moment. Let me know if you find a better solutionAdministration
A
4

I'm not 100% convinced this is the best way to do it, but I managed to make it work visually like I intended it to work using a ZStack:


        ZStack {           
            Button(action: {
                tappedDonate = true
            }, label: {
                Text("Donate")
                    .frame(width: 300, height: 44, alignment: .center)
            })
            .frame(width: 300, height: 20, alignment: .center)
            .padding()
            .background(Color.black)
            .foregroundColor(.white)
            .cornerRadius(22)
            if tappedDonate {
                ApplePayWrapper(request: model.buildApplePayment())
            }
        }

Note that you still need to hook up the cancel button as well as the regular dismiss by tapping outside through the delegate, otherwise the underlying UI with the button does not respond to touch again.

Administration answered 29/6, 2020 at 14:40 Comment(1)
I'm experiencing the exact issues as well. Nice find on handling it via ZStack. There's definitely a memory leak somewhere. When I manually nil out the PK controller instance it works better but still wonky. I can open it again and again after that, but cancel button still doesn't work and events are pretty flaky.Shropshire

© 2022 - 2024 — McMap. All rights reserved.