[PW-148] Add PaywallPresentationConfiguration for per-platform presentation style#1623
Conversation
…e white area Enables `useFullScreenPresentation` option when presenting paywalls on iOS. This fixes an issue where paywalls (especially exit offers) in landscape orientation show a white area on the sides due to `.pageSheet` modal presentation style not covering the full screen. Requires purchases-hybrid-common with `useFullScreenPresentation` support. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…shows-white-area-with
...flutter/ios/purchases_ui_flutter/Sources/purchases_ui_flutter/PurchasesUiFlutterPlugin.swift
Outdated
Show resolved
Hide resolved
|
This PR depends on RevenueCat/purchases-hybrid-common#1472 which adds the Updated approach: Instead of hardcoding |
…shows-white-area-with
|
@rickvdl can you take another look please? :) |
...flutter/ios/purchases_ui_flutter/Sources/purchases_ui_flutter/PurchasesUiFlutterPlugin.swift
Outdated
Show resolved
Hide resolved
…resentation control Replace hardcoded full-screen presentation with an explicit opt-in API, matching the approach in purchases-unity PR #839. Developers can now choose full-screen or sheet presentation per platform instead of having it forced. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…shows-white-area-with Resolve conflicts: adopt main's formatting while keeping useFullScreenPresentation additions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
purchases_ui_flutter/lib/paywall_presentation_configuration.dart
Outdated
Show resolved
Hide resolved
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds fullScreen and defaultConfiguration static constants to PaywallPresentationConfiguration. Adds ==, hashCode, and toString to all three configuration classes. Updates doc comments on style classes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only send useFullScreenPresentation when iOS presentation style is fullScreen, instead of always sending false on Android. Adds tests for android-only config, sheet config, and presentation config class coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r-landscape-exit-offer-shows-white-area-with # Conflicts: # purchases_ui_flutter/ios/purchases_ui_flutter/Sources/purchases_ui_flutter/PurchasesUiFlutterPlugin.swift # purchases_ui_flutter/lib/purchases_ui_flutter.dart
purchases_ui_flutter/lib/paywall_presentation_configuration.dart
Outdated
Show resolved
Hide resolved
purchases_ui_flutter/lib/paywall_presentation_configuration.dart
Outdated
Show resolved
Hide resolved
purchases_ui_flutter/lib/paywall_presentation_configuration.dart
Outdated
Show resolved
Hide resolved
Co-authored-by: Cesar de la Vega <664544+vegaro@users.noreply.github.com>
Co-authored-by: Cesar de la Vega <664544+vegaro@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
purchases_ui_flutter/lib/paywall_presentation_configuration.dart
Outdated
Show resolved
Hide resolved
… useFullScreenPresentation when true - Add CupertinoActionSheet to purchase tester letting you choose Sheet or Full Screen before presenting a paywall - Only include useFullScreenPresentation in iOS plugin options when explicitly provided (never send false) - Add Podfile with platform :ios declaration to fix pod install - Update SKConfig.storekit and wire it to the Xcode scheme Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@rickvdl this is ready to go!! :) |
- Swift: when useFullScreenPresentation is explicitly passed from Dart, use that value; otherwise default to true on iPhone (PW-149 behavior) - Dart: send useFullScreenPresentation: false when IOSPaywallPresentationStyle.sheet is explicitly set, so the iPhone default is not applied when sheet is requested - Update tests to expect useFullScreenPresentation: false for sheet configuration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When no presentationConfiguration is passed, the native default (sheet) applies. Users opt in to full-screen via IOSPaywallPresentationStyle.fullScreen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rickvdl
left a comment
There was a problem hiding this comment.
Nice work, looks good! Couple of points.
Also; I think there are some formatting changes. We could split it to keep the diff smaller, but fine to leave it as well by me.
| } else if UIDevice.current.userInterfaceIdiom == .phone { | ||
| // Default: present paywalls full-screen on iPhone to avoid side white areas | ||
| // in landscape orientation. Keep iPad behavior unchanged. | ||
| options[PaywallProxy.PaywallOptionsKeys.useFullScreenPresentation] = true |
There was a problem hiding this comment.
Here we default to fullscreen on iPhone, but in defaultConfiguration in flutter we set the iOS default to sheet. Maybe we should document a bit better at the default configuration?
There was a problem hiding this comment.
hmm. Does this mean we are changing the default from modal to sheet for people not using the new options?
There was a problem hiding this comment.
The goal is to leave the default as it used to be, and add the options to go fullscreen. It should be like that now. I'll re-test the safe area fix from #1631 and that should be it
There was a problem hiding this comment.
Yes — this PR intentionally changes the default back to sheet (the native SDK default). The previous code had useFullScreenPresentation: true hardcoded, which was the fix for the landscape white-area issue but had the side effect of forcing full-screen everywhere (including iPad). Now it's opt-in: devs who want full screen pass PaywallPresentationConfiguration(ios: IOSPaywallPresentationStyle.fullScreen), and everyone else gets sheet as before.
Remove accidentally committed Podfile (auto-generated), revert Debug.xcconfig extra include line, and restore SKConfig.storekit to the original content. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…files - Gate useFullScreenPresentation to UIDevice.userInterfaceIdiom == .phone so iPad always uses the default sheet presentation - Revert unintended macOS Flutter-Debug/Release.xcconfig changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove iPhone-only guard: devs can pass fullScreen for any device - Revert CocoaPods changes to Release.xcconfig, contents.xcworkspacedata, and project.pbxproj Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uested Avoids sending false when sheet is explicitly set, making it indistinguishable from the default (key absent). Now the key is only sent as true when fullScreen is opted into. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
**This is an automatic release.** ## RevenueCat SDK ### 🐞 Bugfixes * [PW-148] Add PaywallPresentationConfiguration for per-platform presentation style (#1623) via Facundo Menzella (@facumenzella) ### 📦 Dependency Updates * [AUTOMATIC BUMP] Updates purchases-hybrid-common to 17.53.0 (#1692) via RevenueCat Git Bot (@RCGitBot) * [Android 9.27.0](https://github.com/RevenueCat/purchases-android/releases/tag/9.27.0) * [iOS 5.66.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.66.0) ## RevenueCatUI SDK ### 🐞 Bugfixes * [PW-149] Fix PaywallView landscape issue (#1631) via Facundo Menzella (@facumenzella) ### 🔄 Other Changes * Bump json from 2.18.1 to 2.19.2 (#1691) via dependabot[bot] (@dependabot[bot]) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Primarily a versioned release bump across metadata/changelogs with no functional code changes beyond updating reported plugin version strings and dependency versions. > > **Overview** > Bumps the Flutter Purchases and Purchases UI plugins to **`9.15.1`** across `pubspec.yaml`, Gradle, CocoaPods specs, and the runtime-reported plugin version constants (Android/iOS/Web). > > Updates release documentation (`CHANGELOG.md`, `CHANGELOG-LATEST.md`, `VERSIONS.md`) to record the included bugfixes and dependency changes, including `purchases-hybrid-common` **`17.53.0`** (Android `9.27.0`, iOS `5.66.0`) and a `json` dependency bump. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 59eaab9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->

Summary
Fixes landscape white-area issue (PW-148) by adding an explicit opt-in API for controlling paywall presentation style, matching the approach in purchases-unity PR #839.
Usage
Related
Test plan
Note
Medium Risk
Adds a new public API knob that changes iOS paywall presentation behavior and updates the iOS plugin call path; incorrect wiring could affect paywall UX on iOS. Changes are scoped and covered by new unit/API tests, reducing regression risk.
Overview
Adds an opt-in
PaywallPresentationConfigurationAPI (withIOSPaywallPresentationStyle/AndroidPaywallPresentationStyle) and exports it frompurchases_ui_flutter.RevenueCatUI.presentPaywall()andpresentPaywallIfNeeded()now accept an optionalpresentationConfigurationand only send the nativeuseFullScreenPresentationflag when iOS full-screen is explicitly requested (omitting the key preserves the native default sheet behavior).Updates the iOS plugin to accept/pass through
useFullScreenPresentationinstead of always forcing full-screen on iPhone, expands unit tests/API tester coverage for the new argument behavior, and updates the purchase tester example UI to let users choose sheet vs full-screen before presenting a paywall.Written by Cursor Bugbot for commit 35fb97d. This will update automatically on new commits. Configure here.