Skip to content

Instantly share code, notes, and snippets.

@leok7v
Created September 30, 2025 03:42
Show Gist options
  • Select an option

  • Save leok7v/76eb2c6a5c5068aed42fb9df85df36f1 to your computer and use it in GitHub Desktop.

Select an option

Save leok7v/76eb2c6a5c5068aed42fb9df85df36f1 to your computer and use it in GitHub Desktop.
Swift.WebView polyfill
import SwiftUI
import WebKit
import Foundation
import SwiftUI
//import Foundation
#if os(iOS)
import UIKit
typealias OSWindow = UIWindow
typealias OSView = UIView
typealias OSHostingController = UIHostingController
typealias OSViewRepresentable = UIViewRepresentable
#elseif os(macOS)
import AppKit
typealias OSWindow = NSWindow
typealias OSView = NSView
typealias OSHostingController = NSHostingController
typealias OSViewRepresentable = NSViewRepresentable
#endif
public enum UIWebViewAction: Equatable {
case idle,
load(URLRequest),
loadHTML(String),
reload,
goBack,
goForward,
evaluateJS(String, (Result<Any?, Error>) -> Void)
public static func == (lhs: UIWebViewAction, rhs: UIWebViewAction) -> Bool {
if case .idle = lhs, case .idle = rhs { return true }
if case let .load(l) = lhs, case let .load(r) = rhs { return l == r }
if case let .loadHTML(l) = lhs, case let .loadHTML(r) = rhs { return l == r }
if case .reload = lhs, case .reload = rhs { return true }
if case .goBack = lhs, case .goBack = rhs { return true }
if case .goForward = lhs, case .goForward = rhs { return true }
if case let .evaluateJS(l, _) = lhs, case let .evaluateJS(r, _) = rhs { return l == r }
return false
}
}
public struct UIWebViewState: Equatable {
public internal(set) var isLoading: Bool
public internal(set) var pageURL: String?
public internal(set) var pageTitle: String?
public internal(set) var pageHTML: String?
public internal(set) var error: Error?
public internal(set) var canGoBack: Bool
public internal(set) var canGoForward: Bool
public static let empty = UIWebViewState(isLoading: false, pageURL: nil,
pageTitle: nil, pageHTML: nil, error: nil, canGoBack: false,
canGoForward: false)
public static func == (lhs: UIWebViewState, rhs: UIWebViewState) -> Bool {
lhs.isLoading == rhs.isLoading &&
lhs.pageURL == rhs.pageURL &&
lhs.pageTitle == rhs.pageTitle &&
lhs.pageHTML == rhs.pageHTML &&
lhs.error?.localizedDescription == rhs.error?.localizedDescription &&
lhs.canGoBack == rhs.canGoBack &&
lhs.canGoForward == rhs.canGoForward
}
}
public class UIWebViewCoordinator: NSObject {
private let webView: UIWebView
var actionInProgress = false
init(webView: UIWebView) {
self.webView = webView
}
func setLoading(_ isLoading: Bool, canGoBack: Bool? = nil, canGoForward: Bool? = nil, error: Error? = nil) {
var newState = webView.state
newState.isLoading = isLoading
if let canGoBack { newState.canGoBack = canGoBack }
if let canGoForward { newState.canGoForward = canGoForward }
if let error { newState.error = error }
webView.state = newState
webView.action = .idle
actionInProgress = false
}
}
extension UIWebViewCoordinator: WKNavigationDelegate {
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
setLoading(false, canGoBack: webView.canGoBack, canGoForward: webView.canGoForward)
webView.evaluateJavaScript("document.title") { response, _ in
if let title = response as? String {
var newState = self.webView.state
newState.pageTitle = title
self.webView.state = newState
}
}
webView.evaluateJavaScript("document.URL.toString()") { response, _ in
if let url = response as? String {
var newState = self.webView.state
newState.pageURL = url
self.webView.state = newState
}
}
if self.webView.htmlInState {
webView.evaluateJavaScript("document.documentElement.outerHTML.toString()") { response, _ in
if let html = response as? String {
var newState = self.webView.state
newState.pageHTML = html
self.webView.state = newState
}
}
}
if !self.webView.config.allowsTextSelection {
webView.evaluateJavaScript("document.body.style.webkitUserSelect='none';") { _, _ in }
}
}
public func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
setLoading(false)
}
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
setLoading(false, error: error)
}
public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
setLoading(true)
}
public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
setLoading(true, canGoBack: webView.canGoBack, canGoForward: webView.canGoForward)
}
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let host = navigationAction.request.url?.host, self.webView.restrictedPages?.contains(where: { host.contains($0) }) == true {
decisionHandler(.cancel)
setLoading(false)
return
}
if let url = navigationAction.request.url, let scheme = url.scheme, let handler = self.webView.schemeHandlers[scheme] {
handler(url)
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
}
extension UIWebViewCoordinator: WKUIDelegate {
public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
}
public struct UIWebViewConfig {
public static let `default` = UIWebViewConfig()
public let javaScriptEnabled: Bool
public let allowsBackForwardNavigationGestures: Bool
public let allowsInlineMediaPlayback: Bool
public let mediaTypesRequiringUserActionForPlayback: WKAudiovisualMediaTypes
public let isScrollEnabled: Bool
public let isOpaque: Bool
public let backgroundColor: Color
public let scrollBounceBehavior: ScrollBounceBehavior
public let scrollBounceAxes: Axis.Set
public let allowsMagnification: Bool
public let allowsTextSelection: Bool
public let allowsLinkPreviews: Bool
public let allowsElementFullscreen: Bool
public init(javaScriptEnabled: Bool = true,
allowsBackForwardNavigationGestures: Bool = true,
allowsInlineMediaPlayback: Bool = true,
mediaTypesRequiringUserActionForPlayback: WKAudiovisualMediaTypes = [],
isScrollEnabled: Bool = true,
isOpaque: Bool = true,
backgroundColor: Color = .clear,
scrollBounceBehavior: ScrollBounceBehavior = .automatic,
scrollBounceAxes: Axis.Set = [.vertical],
allowsMagnification: Bool = true,
allowsTextSelection: Bool = true,
allowsLinkPreviews: Bool = true,
allowsElementFullscreen: Bool = true) {
self.javaScriptEnabled = javaScriptEnabled
self.allowsBackForwardNavigationGestures = allowsBackForwardNavigationGestures
self.allowsInlineMediaPlayback = allowsInlineMediaPlayback
self.mediaTypesRequiringUserActionForPlayback = mediaTypesRequiringUserActionForPlayback
self.isScrollEnabled = isScrollEnabled
self.isOpaque = isOpaque
self.backgroundColor = backgroundColor
self.scrollBounceBehavior = scrollBounceBehavior
self.scrollBounceAxes = scrollBounceAxes
self.allowsMagnification = allowsMagnification
self.allowsTextSelection = allowsTextSelection
self.allowsLinkPreviews = allowsLinkPreviews
self.allowsElementFullscreen = allowsElementFullscreen
}
}
#if os(macOS)
public typealias ViewRepresentableContext = NSViewRepresentableContext<UIWebView>
#endif
public struct UIWebView: OSViewRepresentable {
public let config: UIWebViewConfig
@Binding public var action: UIWebViewAction
@Binding public var state: UIWebViewState
public let restrictedPages: [String]?
public let htmlInState: Bool
public let schemeHandlers: [String: (URL) -> Void]
public init(config: UIWebViewConfig = .default,
action: Binding<UIWebViewAction>,
state: Binding<UIWebViewState>,
restrictedPages: [String]? = nil,
htmlInState: Bool = false,
schemeHandlers: [String: (URL) -> Void] = [:]) {
self.config = config
_action = action
_state = state
self.restrictedPages = restrictedPages
self.htmlInState = htmlInState
self.schemeHandlers = schemeHandlers
}
#if os(iOS)
public typealias UIViewType = WKWebView
#else
public typealias NSViewType = WKWebView
#endif
public typealias Coordinator = UIWebViewCoordinator
public func makeCoordinator() -> Coordinator {
UIWebViewCoordinator(webView: self)
}
#if os(iOS)
public func makeUIView(context: UIViewRepresentableContext<UIWebView>) -> UIViewType {
let preferences = WKPreferences()
// preferences.javaScriptEnabled = config.javaScriptEnabled
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
configuration.allowsInlineMediaPlayback = config.allowsInlineMediaPlayback
configuration.mediaTypesRequiringUserActionForPlayback = config.mediaTypesRequiringUserActionForPlayback
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.navigationDelegate = context.coordinator
webView.uiDelegate = context.coordinator
webView.allowsBackForwardNavigationGestures = config.allowsBackForwardNavigationGestures
webView.scrollView.isScrollEnabled = config.isScrollEnabled
webView.isOpaque = config.isOpaque
webView.backgroundColor = UIColor(config.backgroundColor)
/* TODO:
webView.scrollView.bounces = config.scrollBounceBehavior == ScrollBounceBehavior.never
webView.scrollView.alwaysBounceVertical = config.scrollBounceBehavior == ScrollBounceBehavior.always && config.scrollBounceAxes.contains(.vertical)
webView.scrollView.alwaysBounceHorizontal = config.scrollBounceBehavior == ScrollBounceBehavior.always && config.scrollBounceAxes.contains(.horizontal)
*/
return webView
}
public func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<UIWebView>) {
if action == .idle || context.coordinator.actionInProgress { return }
context.coordinator.actionInProgress = true
switch action {
case .load(let request):
uiView.load(request)
case .loadHTML(let html):
uiView.loadHTMLString(html, baseURL: nil)
case .reload:
uiView.reload()
case .goBack:
uiView.goBack()
case .goForward:
uiView.goForward()
case let .evaluateJS(command, callback):
uiView.evaluateJavaScript(command) { result, error in
if let error {
callback(.failure(error))
} else {
callback(.success(result))
}
self.action = .idle
context.coordinator.actionInProgress = false
}
return
case .idle:
break
}
}
#else
public func makeNSView(context: ViewRepresentableContext) -> NSViewType {
let preferences = WKPreferences()
// preferences.javaScriptEnabled = config.javaScriptEnabled
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.navigationDelegate = context.coordinator
webView.uiDelegate = context.coordinator
webView.allowsBackForwardNavigationGestures = config.allowsBackForwardNavigationGestures
webView.allowsMagnification = config.allowsMagnification
webView.setValue(config.isOpaque, forKey: "drawsBackground")
// webView.isOpaque = config.isOpaque
// webView.backgroundColor = NSColor(config.backgroundColor)
return webView
}
public func updateNSView(_ nsView: NSViewType, context: ViewRepresentableContext) {
if action == .idle || context.coordinator.actionInProgress { return }
context.coordinator.actionInProgress = true
switch action {
case .load(let request):
nsView.load(request)
case .loadHTML(let html):
nsView.loadHTMLString(html, baseURL: nil)
case .reload:
nsView.reload()
case .goBack:
nsView.goBack()
case .goForward:
nsView.goForward()
case let .evaluateJS(command, callback):
nsView.evaluateJavaScript(command) { result, error in
if let error {
callback(.failure(error))
} else {
callback(.success(result))
}
self.action = .idle
context.coordinator.actionInProgress = false
}
return
case .idle:
break
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.action = .idle
context.coordinator.actionInProgress = false
}
}
#endif
}
extension UIWebView {
public func scrollBounceBehavior(_ behavior: ScrollBounceBehavior, axes: Axis.Set = [.vertical]) -> Self {
UIWebView(config: UIWebViewConfig(javaScriptEnabled: config.javaScriptEnabled,
allowsBackForwardNavigationGestures: config.allowsBackForwardNavigationGestures,
allowsInlineMediaPlayback: config.allowsInlineMediaPlayback,
mediaTypesRequiringUserActionForPlayback: config.mediaTypesRequiringUserActionForPlayback,
isScrollEnabled: config.isScrollEnabled,
isOpaque: config.isOpaque,
backgroundColor: config.backgroundColor,
scrollBounceBehavior: behavior,
scrollBounceAxes: axes,
allowsMagnification: config.allowsMagnification,
allowsTextSelection: config.allowsTextSelection,
allowsLinkPreviews: config.allowsLinkPreviews,
allowsElementFullscreen: config.allowsElementFullscreen),
action: $action,
state: $state,
restrictedPages: restrictedPages,
htmlInState: htmlInState,
schemeHandlers: schemeHandlers)
}
public func webViewBackForwardNavigationGestures(_ enabled: Bool) -> Self {
UIWebView(config: UIWebViewConfig(javaScriptEnabled: config.javaScriptEnabled,
allowsBackForwardNavigationGestures: enabled,
allowsInlineMediaPlayback: config.allowsInlineMediaPlayback,
mediaTypesRequiringUserActionForPlayback: config.mediaTypesRequiringUserActionForPlayback,
isScrollEnabled: config.isScrollEnabled,
isOpaque: config.isOpaque,
backgroundColor: config.backgroundColor,
scrollBounceBehavior: config.scrollBounceBehavior,
scrollBounceAxes: config.scrollBounceAxes,
allowsMagnification: config.allowsMagnification,
allowsTextSelection: config.allowsTextSelection,
allowsLinkPreviews: config.allowsLinkPreviews,
allowsElementFullscreen: config.allowsElementFullscreen),
action: $action,
state: $state,
restrictedPages: restrictedPages,
htmlInState: htmlInState,
schemeHandlers: schemeHandlers)
}
public func webViewMagnificationGestures(_ enabled: Bool) -> Self {
UIWebView(config: UIWebViewConfig(javaScriptEnabled: config.javaScriptEnabled,
allowsBackForwardNavigationGestures: config.allowsBackForwardNavigationGestures,
allowsInlineMediaPlayback: config.allowsInlineMediaPlayback,
mediaTypesRequiringUserActionForPlayback: config.mediaTypesRequiringUserActionForPlayback,
isScrollEnabled: config.isScrollEnabled,
isOpaque: config.isOpaque,
backgroundColor: config.backgroundColor,
scrollBounceBehavior: config.scrollBounceBehavior,
scrollBounceAxes: config.scrollBounceAxes,
allowsMagnification: enabled,
allowsTextSelection: config.allowsTextSelection,
allowsLinkPreviews: config.allowsLinkPreviews,
allowsElementFullscreen: config.allowsElementFullscreen),
action: $action,
state: $state,
restrictedPages: restrictedPages,
htmlInState: htmlInState,
schemeHandlers: schemeHandlers)
}
public func webViewTextSelection(_ enabled: Bool) -> Self {
UIWebView(config: UIWebViewConfig(javaScriptEnabled: config.javaScriptEnabled,
allowsBackForwardNavigationGestures: config.allowsBackForwardNavigationGestures,
allowsInlineMediaPlayback: config.allowsInlineMediaPlayback,
mediaTypesRequiringUserActionForPlayback: config.mediaTypesRequiringUserActionForPlayback,
isScrollEnabled: config.isScrollEnabled,
isOpaque: config.isOpaque,
backgroundColor: config.backgroundColor,
scrollBounceBehavior: config.scrollBounceBehavior,
scrollBounceAxes: config.scrollBounceAxes,
allowsMagnification: config.allowsMagnification,
allowsTextSelection: enabled,
allowsLinkPreviews: config.allowsLinkPreviews,
allowsElementFullscreen: config.allowsElementFullscreen),
action: $action,
state: $state,
restrictedPages: restrictedPages,
htmlInState: htmlInState,
schemeHandlers: schemeHandlers)
}
public func webViewLinkPreviews(_ enabled: Bool) -> Self {
UIWebView(config: UIWebViewConfig(javaScriptEnabled: config.javaScriptEnabled,
allowsBackForwardNavigationGestures: config.allowsBackForwardNavigationGestures,
allowsInlineMediaPlayback: config.allowsInlineMediaPlayback,
mediaTypesRequiringUserActionForPlayback: config.mediaTypesRequiringUserActionForPlayback,
isScrollEnabled: config.isScrollEnabled,
isOpaque: config.isOpaque,
backgroundColor: config.backgroundColor,
scrollBounceBehavior: config.scrollBounceBehavior,
scrollBounceAxes: config.scrollBounceAxes,
allowsMagnification: config.allowsMagnification,
allowsTextSelection: config.allowsTextSelection,
allowsLinkPreviews: enabled,
allowsElementFullscreen: config.allowsElementFullscreen),
action: $action,
state: $state,
restrictedPages: restrictedPages,
htmlInState: htmlInState,
schemeHandlers: schemeHandlers)
}
public func webViewElementFullscreenBehavior(_ enabled: Bool) -> Self {
UIWebView(config: UIWebViewConfig(javaScriptEnabled: config.javaScriptEnabled,
allowsBackForwardNavigationGestures: config.allowsBackForwardNavigationGestures,
allowsInlineMediaPlayback: config.allowsInlineMediaPlayback,
mediaTypesRequiringUserActionForPlayback: config.mediaTypesRequiringUserActionForPlayback,
isScrollEnabled: config.isScrollEnabled,
isOpaque: config.isOpaque,
backgroundColor: config.backgroundColor,
scrollBounceBehavior: config.scrollBounceBehavior,
scrollBounceAxes: config.scrollBounceAxes,
allowsMagnification: config.allowsMagnification,
allowsTextSelection: config.allowsTextSelection,
allowsLinkPreviews: config.allowsLinkPreviews,
allowsElementFullscreen: enabled),
action: $action,
state: $state,
restrictedPages: restrictedPages,
htmlInState: htmlInState,
schemeHandlers: schemeHandlers)
}
public func webViewContentBackground(_ color: Color) -> Self {
UIWebView(config: UIWebViewConfig(javaScriptEnabled: config.javaScriptEnabled,
allowsBackForwardNavigationGestures: config.allowsBackForwardNavigationGestures,
allowsInlineMediaPlayback: config.allowsInlineMediaPlayback,
mediaTypesRequiringUserActionForPlayback: config.mediaTypesRequiringUserActionForPlayback,
isScrollEnabled: config.isScrollEnabled,
isOpaque: config.isOpaque,
backgroundColor: color,
scrollBounceBehavior: config.scrollBounceBehavior,
scrollBounceAxes: config.scrollBounceAxes,
allowsMagnification: config.allowsMagnification,
allowsTextSelection: config.allowsTextSelection,
allowsLinkPreviews: config.allowsLinkPreviews,
allowsElementFullscreen: config.allowsElementFullscreen),
action: $action,
state: $state,
restrictedPages: restrictedPages,
htmlInState: htmlInState,
schemeHandlers: schemeHandlers)
}
}
public struct UIWebPage {
public let url: URL?
public let html: String?
public init(url: URL) {
self.url = url
self.html = nil
}
public init(html: String) {
self.url = nil
self.html = html
}
}
extension UIWebView {
public init(page: UIWebPage, config: UIWebViewConfig = .default,
state: Binding<UIWebViewState>,
restrictedPages: [String]? = nil, htmlInState: Bool = false,
schemeHandlers: [String: (URL) -> Void] = [:]) {
self.init(config: config, action: .constant(.idle), state: state,
restrictedPages: restrictedPages, htmlInState: htmlInState,
schemeHandlers: schemeHandlers)
if let url = page.url {
action = .load(URLRequest(url: url))
} else if let html = page.html {
action = .loadHTML(html)
}
}
}
struct WebViewTest: View {
@State private var action = UIWebViewAction.idle
@State private var state = UIWebViewState.empty
@State private var address = "https://www.google.com"
var body: some View {
VStack {
titleView
navigationToolbar
errorView
Divider()
UIWebView(action: $action,
state: $state,
restrictedPages: ["apple.com"],
htmlInState: true)
// Text(state.pageHTML ?? "").lineLimit(nil)
Spacer()
}
}
private var titleView: some View {
Text(String(format: "%@ - %@", state.pageTitle ?? "Load a page", state.pageURL ?? "No URL"))
.font(.system(size: 24))
}
private var navigationToolbar: some View {
HStack(spacing: 10) {
Button("Test HTML") {
action = .loadHTML("""
<html><body>
<b>Hello World!</b><br />
<a href="https://www.google.com" target="_blank">Go to google</a>
</body></html>
""")
state.error = nil
}
TextField("Address", text: $address)
if state.isLoading {
if #available(iOS 14, macOS 11, *) {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
} else {
Text("Loading")
}
}
Spacer()
Button("Go") {
if let url = URL(string: address) {
action = .load(URLRequest(url: url))
}
}
Button(action: {
action = .reload
}) {
if #available(iOS 14, macOS 11, *) {
Image(systemName: "arrow.counterclockwise")
.imageScale(.large)
} else {
Text("Reload")
}
}
if state.canGoBack {
Button(action: {
action = .goBack
}) {
if #available(iOS 14, macOS 11, *) {
Image(systemName: "chevron.left")
.imageScale(.large)
} else {
Text("<")
}
}
}
if state.canGoForward {
Button(action: {
action = .goForward
}) {
if #available(iOS 14, macOS 11, *) {
Image(systemName: "chevron.right")
.imageScale(.large)
} else {
Text(">")
}
}
}
}.padding()
}
private var errorView: some View {
Group {
if let error = state.error {
Text(error.localizedDescription)
.foregroundColor(.red)
}
}
}
}
struct WebView_Previews: PreviewProvider {
static var previews: some View {
WebViewTest()
}
}
import SwiftUI
import WebKit
import Foundation
public enum UIWebViewAction : Equatable {
case idle, load(URLRequest), loadHTML(String), reload, goBack, goForward, evaluateJS(String, (Result<Any?, Error>) -> Void)
/// Returns a Boolean value indicating whether two values are equal.
///
/// Equality is the inverse of inequality. For any values `a` and `b`,
/// `a == b` implies that `a != b` is `false`.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
public static func == (lhs: UIWebViewAction, rhs: UIWebViewAction) -> Bool
}
public struct UIWebViewState : Equatable {
public internal(set) var isLoading: Bool { get }
public internal(set) var pageURL: String? { get }
public internal(set) var pageTitle: String? { get }
public internal(set) var pageHTML: String? { get }
public internal(set) var error: Error? { get }
public internal(set) var canGoBack: Bool { get }
public internal(set) var canGoForward: Bool { get }
public static let empty: UIWebView.UIWebViewState
/// Returns a Boolean value indicating whether two values are equal.
///
/// Equality is the inverse of inequality. For any values `a` and `b`,
/// `a == b` implies that `a != b` is `false`.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
public static func == (lhs: UIWebViewState, rhs: UIWebViewState) -> Bool
}
public class UIWebViewCoordinator : NSObject {
internal var actionInProgress: Bool
internal init(webView: UIWebView)
internal func setLoading(_ isLoading: Bool, canGoBack: Bool? = nil, canGoForward: Bool? = nil, error: Error? = nil)
}
extension UIWebViewCoordinator : WKNavigationDelegate {
@MainActor public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
@MainActor public func webViewWebContentProcessDidTerminate(_ webView: WKWebView)
@MainActor public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error)
@MainActor public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!)
@MainActor public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
@MainActor public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
}
extension UIWebViewCoordinator : WKUIDelegate {
@MainActor public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?
}
public struct UIWebViewConfig {
public static let `default`: UIWebView.UIWebViewConfig
public let javaScriptEnabled: Bool
public let allowsBackForwardNavigationGestures: Bool
public let allowsInlineMediaPlayback: Bool
public let mediaTypesRequiringUserActionForPlayback: WKAudiovisualMediaTypes
public let isScrollEnabled: Bool
public let isOpaque: Bool
public let backgroundColor: Color
public let scrollBounceBehavior: ScrollBounceBehavior
public let scrollBounceAxes: Axis.Set
public let allowsMagnification: Bool
public let allowsTextSelection: Bool
public let allowsLinkPreviews: Bool
public let allowsElementFullscreen: Bool
public init(javaScriptEnabled: Bool = true, allowsBackForwardNavigationGestures: Bool = true, allowsInlineMediaPlayback: Bool = true, mediaTypesRequiringUserActionForPlayback: WKAudiovisualMediaTypes = [], isScrollEnabled: Bool = true, isOpaque: Bool = true, backgroundColor: Color = .clear, scrollBounceBehavior: ScrollBounceBehavior = .automatic, scrollBounceAxes: Axis.Set = [.vertical], allowsMagnification: Bool = true, allowsTextSelection: Bool = true, allowsLinkPreviews: Bool = true, allowsElementFullscreen: Bool = true)
}
public typealias ViewRepresentableContext = NSViewRepresentableContext<UIWebView>
public struct UIWebView : OSViewRepresentable {
public let config: UIWebViewConfig
@Binding public var action: UIWebViewAction { get nonmutating set }
@Binding public var state: UIWebViewState { get nonmutating set }
public let restrictedPages: [String]?
public let htmlInState: Bool
public let schemeHandlers: [String : (URL) -> Void]
public init(config: UIWebViewConfig = .default, action: Binding<UIWebViewAction>, state: Binding<UIWebViewState>, restrictedPages: [String]? = nil, htmlInState: Bool = false, schemeHandlers: [String : (URL) -> Void] = [:])
public typealias NSViewType = WKWebView
public typealias Coordinator = UIWebViewCoordinator
public func makeCoordinator() -> Coordinator
public func makeNSView(context: ViewRepresentableContext) -> NSViewType
public func updateNSView(_ nsView: NSViewType, context: ViewRepresentableContext)
}
extension UIWebView {
public func scrollBounceBehavior(_ behavior: ScrollBounceBehavior, axes: Axis.Set = [.vertical]) -> UIWebView.UIWebView
public func webViewBackForwardNavigationGestures(_ enabled: Bool) -> UIWebView.UIWebView
public func webViewMagnificationGestures(_ enabled: Bool) -> UIWebView.UIWebView
public func webViewTextSelection(_ enabled: Bool) -> UIWebView.UIWebView
public func webViewLinkPreviews(_ enabled: Bool) -> UIWebView.UIWebView
public func webViewElementFullscreenBehavior(_ enabled: Bool) -> UIWebView.UIWebView
public func webViewContentBackground(_ color: Color) -> UIWebView.UIWebView
}
public struct UIWebPage {
public let url: URL?
public let html: String?
public init(url: URL)
public init(html: String)
}
extension UIWebView {
public init(page: UIWebPage, config: UIWebViewConfig = .default, state: Binding<UIWebViewState>, restrictedPages: [String]? = nil, htmlInState: Bool = false, schemeHandlers: [String : (URL) -> Void] = [:])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment