From 59700eaa78eac1ec905f4fa1d37185492b3d8dba Mon Sep 17 00:00:00 2001 From: NachoSoto Date: Wed, 2 Aug 2023 09:18:13 -0700 Subject: [PATCH] `Paywalls`: improved `IntroEligibilityStateView` to avoid layout changes (#2946) --- .../Views/IntroEligibilityStateView.swift | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/RevenueCatUI/Views/IntroEligibilityStateView.swift b/RevenueCatUI/Views/IntroEligibilityStateView.swift index c83052ef9d..5e35ef770f 100644 --- a/RevenueCatUI/Views/IntroEligibilityStateView.swift +++ b/RevenueCatUI/Views/IntroEligibilityStateView.swift @@ -37,6 +37,8 @@ struct IntroEligibilityStateView: View { // Hide until we've determined intro eligibility // only if there is a custom intro text. .withPendingData(self.needsToWaitForIntroEligibility, alignment: self.alignment) + // Hide if there is no intro but we have no text to ensure layout does not change. + .hidden(if: self.isNotEligibleForIntro && self.textWithNoIntroOffer.isEmpty) .foregroundColor(self.foregroundColor) .tint(self.foregroundColor) } @@ -45,7 +47,9 @@ struct IntroEligibilityStateView: View { if let textWithIntroOffer = self.textWithIntroOffer, self.isEligibleForIntro { return textWithIntroOffer } else { - return self.textWithNoIntroOffer + // Display text with intro offer as a backup to ensure layout does not change + // when switching states. + return self.textWithNoIntroOffer.notEmpty ?? self.textWithIntroOffer ?? "" } } @@ -60,6 +64,10 @@ private extension IntroEligibilityStateView { return self.introEligibility?.isEligible != false } + var isNotEligibleForIntro: Bool { + return self.introEligibility?.isEligible == false + } + var needsToWaitForIntroEligibility: Bool { return self.introEligibility == nil && self.textWithIntroOffer != nil } @@ -83,3 +91,9 @@ private extension View { } } + +private extension String { + + var notEmpty: String? { return self.isEmpty ? nil : self } + +}