This took me FOREVER to figure out, so maybe someone will find this helpful:
Basically, it's not enough to just wrap the button in a UIViewRepresentable. You have to put
that in a ButtonStyle, and then style a SwiftUI button with it. If you don't, it seems like your payment sheet will break! I'm not sure why this is true, but here's the code as it should work:
Code Block swift| import SwiftUI |
| import UIKit |
| import PassKit |
|
| struct PaymentButton: View { |
| var body: some View { |
| Button(action: { |
| /* Your custom payment code here */ |
| }, label: { EmptyView() } ) |
| .buttonStyle(PaymentButtonStyle()) |
| } |
| } |
|
| struct PaymentButtonStyle: ButtonStyle { |
| func makeBody(configuration: Self.Configuration) -> some View { |
| return PaymentButtonHelper() |
| } |
| } |
|
| struct PaymentButtonHelper: View { |
| var body: some View { |
| PaymentButtonRepresentable() |
| .frame(minWidth: 100, maxWidth: 400) |
| .frame(height: 60) |
| .frame(maxWidth: .infinity) |
| } |
| } |
|
| extension PaymentButtonHelper { |
| struct PaymentButtonRepresentable: UIViewRepresentable { |
| |
| var button: PKPaymentButton { |
| let button = PKPaymentButton(paymentButtonType: .buy, paymentButtonStyle: .black) /*customize here*/ |
| button.cornerRadius = 4.0 /* also customize here */ |
| return button |
| } |
| |
| func makeUIView(context: Context) -> PKPaymentButton { |
| return button |
| } |
| func updateUIView(_ uiView: PKPaymentButton, context: Context) { } |
| } |
| } |
You can also use the button entirely in SwiftUI using
iPaymentButton. Example usage would look like:
Code Block swift| import SwiftUI |
| import iPaymentButton |
|
| struct ContentView: View { |
| var body: some View { |
| iPaymentButton(type: .support, style: .whiteOutline, action: { |
| /* Add your custom payment code here */ |
| }) |
| } |
| } |
Import instructions on iSwiftUI 👉