Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
47
iphone/Maps/Bridging/BridgeControllers.swift
Normal file
47
iphone/Maps/Bridging/BridgeControllers.swift
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import SwiftUI
|
||||
import UIKit
|
||||
|
||||
/// Class for accesing SwiftUI views from Objective-C code
|
||||
@objc class BridgeControllers: NSObject {
|
||||
/// The `ProfileView` for presentation in an alert
|
||||
@objc static func profileAsAlert() -> UIViewController {
|
||||
let profileBridgeController = UIHostingController(rootView: ProfileView(isPresentedAsAlert: true))
|
||||
profileBridgeController.view.backgroundColor = .systemGroupedBackground
|
||||
return profileBridgeController
|
||||
}
|
||||
|
||||
/// The `RoutingOptionsView` for presentation in an alert
|
||||
@objc static func routingOptions() -> UIViewController {
|
||||
let routinOptionsBridgeController = UIHostingController(rootView: RoutingOptionsView())
|
||||
routinOptionsBridgeController.view.backgroundColor = .systemGroupedBackground
|
||||
return routinOptionsBridgeController
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Class for using the SwiftUI `AboutView` in the interface builder
|
||||
class AboutBridgeController: UIHostingController<AboutView> {
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder, rootView: AboutView())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Class for using the SwiftUI `SettingsView` in the interface builder
|
||||
class SettingsBridgeController: UIHostingController<SettingsView> {
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder, rootView: SettingsView())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Class for using the SwiftUI `ProfileView` in the interface builder
|
||||
class ProfileBridgeController: UIHostingController<ProfileView> {
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder, rootView: ProfileView())
|
||||
self.view.tintColor = .toolbarAccent
|
||||
}
|
||||
}
|
||||
42
iphone/Maps/Bridging/EmbeddedSafariView.swift
Normal file
42
iphone/Maps/Bridging/EmbeddedSafariView.swift
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import SwiftUI
|
||||
|
||||
/// View for Safari via a WebKit view
|
||||
struct EmbeddedSafariView: View {
|
||||
// MARK: Properties
|
||||
|
||||
/// If the content is loading
|
||||
@State private var isLoading: Bool = true
|
||||
|
||||
|
||||
/// The view height
|
||||
@State private var height: CGFloat = .zero
|
||||
|
||||
|
||||
/// The url
|
||||
let url: URL
|
||||
|
||||
|
||||
/// If the view should resize itself to the height of the website content
|
||||
var hasDynamicHeight: Bool = true
|
||||
|
||||
|
||||
/// The actual view
|
||||
var body: some View {
|
||||
ZStack {
|
||||
if hasDynamicHeight {
|
||||
EmbeddedSafariViewContent(isLoading: $isLoading, height: $height, hasDynamicHeight: hasDynamicHeight, url: url)
|
||||
.frame(height: .infinity)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
} else {
|
||||
EmbeddedSafariViewContent(isLoading: $isLoading, height: $height, hasDynamicHeight: hasDynamicHeight, url: url)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
|
||||
if isLoading {
|
||||
ProgressView()
|
||||
.controlSize(.large)
|
||||
.frame(minHeight: 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
iphone/Maps/Bridging/EmbeddedSafariViewContent.swift
Normal file
59
iphone/Maps/Bridging/EmbeddedSafariViewContent.swift
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import SwiftUI
|
||||
import WebKit
|
||||
|
||||
/// Content of the view for Safari via a WebKit view
|
||||
struct EmbeddedSafariViewContent: UIViewRepresentable {
|
||||
// MARK: Properties
|
||||
|
||||
/// If the content is loading
|
||||
@Binding var isLoading: Bool
|
||||
|
||||
|
||||
/// The view height
|
||||
@Binding var height: CGFloat
|
||||
|
||||
|
||||
/// If the view should resize itself to the height of the website content
|
||||
var hasDynamicHeight: Bool = true
|
||||
|
||||
|
||||
/// The url
|
||||
let url: URL
|
||||
|
||||
|
||||
|
||||
// MARK: Methods
|
||||
|
||||
/// Create a coodindator for the WebKit view
|
||||
func makeCoordinator() -> EmbeddedSafariViewCoordinator {
|
||||
EmbeddedSafariViewCoordinator(self)
|
||||
}
|
||||
|
||||
|
||||
/// Create a WebKit view
|
||||
/// - Parameter context: The context
|
||||
/// - Returns: The WebKit view
|
||||
func makeUIView(context: UIViewRepresentableContext<EmbeddedSafariViewContent>) -> WKWebView {
|
||||
let uiView = WKWebView()
|
||||
uiView.navigationDelegate = context.coordinator
|
||||
uiView.scrollView.isScrollEnabled = !hasDynamicHeight
|
||||
uiView.scrollView.showsHorizontalScrollIndicator = false
|
||||
uiView.allowsBackForwardNavigationGestures = false
|
||||
uiView.allowsLinkPreview = false
|
||||
if #available(iOS 16.0, *) {
|
||||
uiView.isFindInteractionEnabled = false
|
||||
}
|
||||
uiView.isOpaque = false
|
||||
uiView.backgroundColor = .clear
|
||||
uiView.underPageBackgroundColor = .clear
|
||||
uiView.load(URLRequest(url: url))
|
||||
return uiView
|
||||
}
|
||||
|
||||
|
||||
/// Update the WebKit view
|
||||
/// - Parameter context: The context
|
||||
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<EmbeddedSafariViewContent>) {
|
||||
uiView.load(URLRequest(url: url))
|
||||
}
|
||||
}
|
||||
57
iphone/Maps/Bridging/EmbeddedSafariViewCoordinator.swift
Normal file
57
iphone/Maps/Bridging/EmbeddedSafariViewCoordinator.swift
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import WebKit
|
||||
|
||||
/// Coordinator of the view for Safari via a WebKit view
|
||||
class EmbeddedSafariViewCoordinator: NSObject {
|
||||
// MARK: Properties
|
||||
|
||||
/// The content
|
||||
var content: EmbeddedSafariViewContent
|
||||
|
||||
|
||||
// MARK: Initialization
|
||||
|
||||
/// Initalize the coordinator with the matching content
|
||||
/// - Parameter content: The content
|
||||
init(_ content: EmbeddedSafariViewContent) {
|
||||
self.content = content
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: - `WKNavigationDelegate`
|
||||
extension EmbeddedSafariViewCoordinator: WKNavigationDelegate {
|
||||
// MARK: Methods
|
||||
|
||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
if webView.isLoading == false {
|
||||
self.content.isLoading = false
|
||||
|
||||
if content.hasDynamicHeight {
|
||||
webView.evaluateJavaScript(
|
||||
"document.body.scrollHeight",
|
||||
completionHandler: { (result, error) in
|
||||
if let height = result as? CGFloat {
|
||||
self.content.height = height
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping @MainActor (WKNavigationActionPolicy) -> Void) {
|
||||
if let url = navigationAction.request.url {
|
||||
if url.absoluteString.starts(with: "file:///") {
|
||||
decisionHandler(.allow)
|
||||
return
|
||||
} else if navigationAction.navigationType == .linkActivated {
|
||||
if UIApplication.shared.canOpenURL(url) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decisionHandler(.cancel)
|
||||
}
|
||||
}
|
||||
44
iphone/Maps/Bridging/SafariView.swift
Normal file
44
iphone/Maps/Bridging/SafariView.swift
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import SafariServices
|
||||
import SwiftUI
|
||||
|
||||
/// View for Safari via a Safari view controller
|
||||
struct SafariView: UIViewControllerRepresentable {
|
||||
// MARK: Properties
|
||||
|
||||
/// The notification name for dismissing this view
|
||||
static let dismissNotificationName: Notification.Name = Notification.Name(rawValue: "DismissSafariView")
|
||||
|
||||
|
||||
/// The url
|
||||
let url: URL
|
||||
|
||||
|
||||
/// The type of dismiss button
|
||||
var dismissButton: SFSafariViewController.DismissButtonStyle = .done
|
||||
|
||||
|
||||
|
||||
// MARK: Methods
|
||||
|
||||
/// Create a Safari view controller
|
||||
/// - Parameter context: The context
|
||||
/// - Returns: The Safari view controller
|
||||
func makeUIViewController(context: UIViewControllerRepresentableContext<SafariView>) -> SFSafariViewController {
|
||||
let safariViewControllerConfiguration = SFSafariViewController.Configuration()
|
||||
safariViewControllerConfiguration.activityButton = nil
|
||||
safariViewControllerConfiguration.barCollapsingEnabled = true
|
||||
|
||||
let safariViewController = SFSafariViewController(url: url, configuration: safariViewControllerConfiguration)
|
||||
safariViewController.preferredBarTintColor = UIColor.accent
|
||||
safariViewController.preferredControlTintColor = UIColor.white
|
||||
safariViewController.dismissButtonStyle = dismissButton
|
||||
return safariViewController
|
||||
}
|
||||
|
||||
|
||||
/// Update the Safari view controller
|
||||
/// - Parameter context: The context
|
||||
func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext<SafariView>) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue