Displaying Paywalls
Displaying Paywalls
How to display a fullscreen Paywall in your app
RevenueCat Paywalls will, by default, show paywalls fullscreen and there are multiple ways to do this with SwiftUI and UIKit.
- Depending on an entitlement with
presentPaywallIfNeeded
- Custom logic with
presentPaywallIfNeeded
- Manually with
PaywallView
orPaywallViewController
import SwiftUI
import RevenueCat
import RevenueCatUI
struct App: View {
var body: some View {
ContentView()
.presentPaywallIfNeeded(
requiredEntitlementIdentifier: "pro",
purchaseCompleted: { customerInfo in
print("Purchase completed: \(customerInfo.entitlements)")
},
restoreCompleted: { customerInfo in
// Paywall will be dismissed automatically if "pro" is now active.
print("Purchases restored: \(customerInfo.entitlements)")
}
)
}
}
import SwiftUI
import RevenueCat
import RevenueCatUI
struct App: View {
var body: some View {
ContentView()
.presentPaywallIfNeeded { customerInfo in
// Returning `true` will present the paywall
return customerInfo.entitlements.active.keys.contains("pro")
} purchaseCompleted: { customerInfo in
print("Purchase completed: \(customerInfo.entitlements)")
} restoreCompleted: {
// Paywall will be dismissed automatically if "pro" is now active.
print("Purchases restored: \(customerInfo.entitlements)")
}
}
}
import SwiftUI
import RevenueCat
import RevenueCatUI
struct App: View {
@State
var displayPaywall = false
var body: some View {
ContentView()
.sheet(isPresented: self.$displayPaywall) {
PaywallView()
// PaywallView does not have a close button
// Manually add one to match your app's style
.toolbar {
ToolbarItem(placement: .destructiveAction) {
Button {
self.displayPaywall = false
} label: {
Image(systemName: "xmark")
}
}
}
}
}
}
import UIKit
import RevenueCat
import RevenueCatUI
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func presentPaywall() {
let controller = PaywallViewController()
controller.delegate = self
present(controller, animated: true, completion: nil)
}
}
extension ViewController: PaywallViewControllerDelegate {
func paywallViewController(_ controller: PaywallViewController,
didFinishPurchasingWith customerInfo: CustomerInfo) {
}
}
Close Button
Paywalls displayed with presentPaywallIfNeeded
will have a close button on the presented sheet. However, a PaywallView
will not have a close button. This gives you full control on how to to navigate to and from your PaywallView
. You can push it onto an existing navigation stack or show it in a sheet with a custom dismiss button using SwiftUI toolbar.
How to display a footer Paywall on your custom paywall
RevenueCatUI also has a paywall variation that can be displayed as a footer below your custom paywall. This allows you to design your paywall exactly as you want with native components while still using RevenueCat UI to handle it. This is done by adding the .paywallFooter()
view modifier to your view.
The footer paywall mainly consists of the following:
- Purchase button
- Package details text
- Package selection (if there are any multiple packages configured)
This is all remotely configured and RevenueCatUI handles all the intro offer eligibility and purchase logic.
import SwiftUI
import RevenueCat
import RevenueCatUI
struct YourPaywall: View {
var body: some View {
ScrollView {
// Your custom paywall design content
}
.paywallFooter()
}
}
import SwiftUI
import RevenueCat
import RevenueCatUI
struct YourPaywall: View {
let offering: Offering
var body: some View {
ScrollView {
// Your custom paywall design content
}
.paywallFooter(offering: offering, condensed: true) { customerInfo in
// Purchase completed! Thank your user and dismiss your paywall
}
}
}
Customization
How to use custom fonts
Paywalls can be configured to use the same font as your app using a PaywallFontProvider
. A PaywallFontProvider
can be passed as an argument into all methods for displaying the paywall.
By default, a paywall will use the DefaultPaywallFontProvider
. This uses the system default font which supports dynamic type.
We also offer a CustomPaywallFontProvider
which requires a font name that could be something like "Arial" or "Papyrus".
If you need more control over your font preferences, you can create your own PaywallFontProvider
. One of the following examples will use a rounded system font in the paywall.
import SwiftUI
import RevenueCat
import RevenueCatUI
struct App: View {
var body: some View {
ContentView()
.presentPaywallIfNeeded(
fonts: CustomPaywallFontProvider(fontName: "Arial")
) { customerInfo in
// Returning `true` will present the paywall
return customerInfo.entitlements.active.keys.contains("pro")
}
}
}
import SwiftUI
import RevenueCat
import RevenueCatUI
struct App: View {
var body: some View {
ContentView()
.presentPaywallIfNeeded(
fonts: RoundedSystemFontProvider()
) { customerInfo in
// Returning `true` will present the paywall
return customerInfo.entitlements.active.keys.contains("pro")
}
}
}
class RoundedSystemFontProvider: PaywallFontProvider {
func font(for textStyle: Font.TextStyle) -> Font {
return Font.system(textStyle, design: .rounded)
}
}
Default Paywall
If you attempt to display a Paywall for an Offering that doesn't have one configured, the RevenueCatUI SDK will display a default Paywall.
The default paywall displays all packages in the offering.
On iOS it uses the app's accentColor
for styling.
Updated 8 days ago