Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

View 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
}
}

View 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)
}
}
}
}

View 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))
}
}

View 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)
}
}

View 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
}
}