Skip to content

Commit

Permalink
Use window.farthestPresentedViewController on presentation
Browse files Browse the repository at this point in the history
  • Loading branch information
stleamist committed Oct 29, 2023
1 parent 10357f5 commit 6ff7a13
Showing 1 changed file with 16 additions and 22 deletions.
38 changes: 16 additions & 22 deletions Sources/BetterSafariView/SafariView/SafariViewPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import SwiftUI
import SafariServices

// `SafariViewPresenter` conforms `UIViewRepresentable` instead of `UIViewControllerRepresentable`.
// This fixes an issue where the Safari view controller is not presented properly
// when the `UIViewControllerRepresentable` is detached from the root view controller
// (e.g. `UIViewController` contained in `UITableViewCell`).
struct SafariViewPresenter<Item: Identifiable>: UIViewRepresentable {

// MARK: Representation
Expand Down Expand Up @@ -80,30 +84,20 @@ extension SafariViewPresenter {
safariViewController.delegate = self
representation.applyModification(to: safariViewController)

if #available(iOS 17.0, *) {
if var topController = UIApplication.shared.windows.filter(\.isKeyWindow).first?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
topController.present(safariViewController, animated: true, completion: nil)
}
self.safariViewController = safariViewController
// Presents a Safari view controller from the farthest `presentedViewController` of `UIWindow`.
// (same approach when presenting `UIAlertController`)
guard let presentingViewController = uiView.window?.farthestPresentedViewController else {
assertionFailure(
"Cannot find the view controller to present from."
+ " This happens when a 'SafariViewPresenter' is detached from the window, or the window doesn't have 'rootViewController.'"
)
self.resetItemBinding()
return
} else {
// Present a Safari view controller from the `viewController` of `UIViewRepresentable`, instead of `UIViewControllerRepresentable`.
// This fixes an issue where the Safari view controller is not presented properly
// when the `UIViewControllerRepresentable` is detached from the root view controller (e.g. `UIViewController` contained in `UITableViewCell`)
// while allowing it to be presented even on the modal sheets.
// Thanks to: Bohdan Hernandez Navia (@boherna)
guard let presentingViewController = uiView.viewController else {
self.resetItemBinding()
return
}

presentingViewController.present(safariViewController, animated: true)

self.safariViewController = safariViewController
}

presentingViewController.present(safariViewController, animated: true)

self.safariViewController = safariViewController
}

private func updateSafariViewController(with item: Item) {
Expand Down

0 comments on commit 6ff7a13

Please sign in to comment.