Skip to content

Commit

Permalink
Consolidate and improve UIViewController traversing
Browse files Browse the repository at this point in the history
  • Loading branch information
porter-stripe committed Feb 3, 2025
1 parent 8b98616 commit 4c21ed7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import SwiftUI
@_spi(STP) import StripeCore
@_spi(STP) import StripeUICore

struct EmbeddedViewRepresentable: UIViewRepresentable {
@ObservedObject var viewModel: EmbeddedPaymentElementViewModel
Expand Down Expand Up @@ -43,26 +44,8 @@ struct EmbeddedViewRepresentable: UIViewRepresentable {

// MARK: UIWindow and UIViewController helpers

extension UIWindow {
extension UIWindow {
static var visibleViewController: UIViewController? {
UIApplication.shared.stp_hackilyFumbleAroundUntilYouFindAKeyWindow()?.rootViewController?.topMostViewController
UIApplication.shared.stp_hackilyFumbleAroundUntilYouFindAKeyWindow()?.rootViewController?.findTopMostPresentedViewController()
}
}

extension UIViewController {
var topMostViewController: UIViewController {
if let nav = self as? UINavigationController {
// Use visibleViewController for navigation stacks
return nav.visibleViewController?.topMostViewController ?? nav
} else if let tab = self as? UITabBarController {
// Use selectedViewController for tab controllers
return tab.selectedViewController?.topMostViewController ?? tab
} else if let presented = presentedViewController {
// Recurse for any presented controllers
return presented.topMostViewController
}

return self
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ extension BottomSheetViewController: UIScrollViewDelegate {
extension BottomSheetViewController: PaymentSheetAuthenticationContext {

func authenticationPresentingViewController() -> UIViewController {
return findTopMostPresentedViewController() ?? self
return findTopMostPresentedViewController()
}

func configureSafariViewController(_ viewController: SFSafariViewController) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,20 @@ import UIKit
return self
}

/// Walks the presented view controller hierarchy and return the top most presented controller.
/// - Returns: Returns the top most presented view controller, or `nil` if this view controller is not presenting another controller.
func findTopMostPresentedViewController() -> UIViewController? {
var topMostController = self.presentedViewController

while let presented = topMostController?.presentedViewController {
topMostController = presented
/// Returns the topmost view controller in the hierarchy.
/// - Returns: The topmost `UIViewController`, or `self` if no higher controller is found.
func findTopMostPresentedViewController() -> UIViewController {
if let nav = self as? UINavigationController {
// Use visibleViewController for navigation stacks
return nav.visibleViewController?.findTopMostPresentedViewController() ?? nav
} else if let tab = self as? UITabBarController {
// Use selectedViewController for tab controllers
return tab.selectedViewController?.findTopMostPresentedViewController() ?? tab
} else if let presented = presentedViewController {
// Recurse for any presented controllers
return presented.findTopMostPresentedViewController()
}

return topMostController
return self
}
}

0 comments on commit 4c21ed7

Please sign in to comment.