Fix laggy Safari presenter

This commit is contained in:
Thomas Ricouard 2023-02-02 07:04:51 +01:00
parent 10946fef10
commit 60f8df9a04

View File

@ -14,7 +14,7 @@ private struct SafariRouter: ViewModifier {
@EnvironmentObject private var preferences: UserPreferences @EnvironmentObject private var preferences: UserPreferences
@EnvironmentObject private var routerPath: RouterPath @EnvironmentObject private var routerPath: RouterPath
@State private var safari: SFSafariViewController? @State private var presentedURL: URL?
func body(content: Content) -> some View { func body(content: Content) -> some View {
content content
@ -46,57 +46,28 @@ private struct SafariRouter: ViewModifier {
return .systemAction return .systemAction
} }
let safari = SFSafariViewController(url: url)
safari.preferredBarTintColor = UIColor(theme.primaryBackgroundColor)
safari.preferredControlTintColor = UIColor(theme.tintColor)
self.safari = safari
presentedURL = url
return .handled return .handled
} }
} }
.background { .sheet(item: $presentedURL, content: { url in
SafariPresenter(safari: safari) SafariView(url: url)
} .edgesIgnoringSafeArea(.all)
})
} }
struct SafariPresenter: UIViewRepresentable { struct SafariView: UIViewControllerRepresentable {
var safari: SFSafariViewController? let url: URL
func makeUIView(context _: Context) -> UIView { func makeUIViewController(context _: UIViewControllerRepresentableContext<SafariView>) -> SFSafariViewController {
let view = UIView(frame: .zero) let safari = SFSafariViewController(url: url)
view.isHidden = true safari.preferredBarTintColor = UIColor(Theme.shared.primaryBackgroundColor)
view.isUserInteractionEnabled = false safari.preferredControlTintColor = UIColor(Theme.shared.tintColor)
return view return safari
} }
func updateUIView(_ uiView: UIView, context _: Context) { func updateUIViewController(_: SFSafariViewController, context _: UIViewControllerRepresentableContext<SafariView>) {}
guard let safari = safari, let viewController = uiView.findTopViewController() else { return }
viewController.present(safari, animated: true)
}
}
}
private extension UIView {
func findTopViewController() -> UIViewController? {
if let nextResponder = next as? UIViewController {
return nextResponder.topViewController()
} else if let nextResponder = next as? UIView {
return nextResponder.findTopViewController()
} else {
return nil
}
}
}
private extension UIViewController {
func topViewController() -> UIViewController? {
if let nvc = self as? UINavigationController {
return nvc.visibleViewController?.topViewController()
} else if let tbc = self as? UITabBarController, let selected = tbc.selectedViewController {
return selected.topViewController()
} else if let presented = presentedViewController {
return presented.topViewController()
}
return self
} }
} }