SwiftUIでWebViewを使うを参考にした。
import SwiftUI
import WebKit
public class SUIWebBrowserObject: WKWebView, WKNavigationDelegate, ObservableObject {
private var observers: [NSKeyValueObservation?] = []
private func subscriber<Value>(for keyPath: KeyPath<SUIWebBrowserObject, Value>) -> NSKeyValueObservation {
observe(keyPath, options: [.prior]) { object, change in
if change.isPrior {
self.objectWillChange.send()
}
}
}
private func setupObservers() {
observers = [
subscriber(for: \.title),
subscriber(for: \.url),
subscriber(for: \.isLoading),
subscriber(for: \.estimatedProgress),
subscriber(for: \.hasOnlySecureContent),
subscriber(for: \.serverTrust),
subscriber(for: \.canGoBack),
subscriber(for: \.canGoForward)
]
}
public override init(frame: CGRect = .zero, configuration: WKWebViewConfiguration = WKWebViewConfiguration()) {
super.init(frame: frame, configuration: configuration)
navigationDelegate = self
setupObservers()
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
navigationDelegate = self
setupObservers()
}
}
public struct SUIWebBrowserView: UIViewRepresentable {
public typealias UIViewType = UIView
private var browserObject: SUIWebBrowserObject
public init(browserObject: SUIWebBrowserObject) {
self.browserObject = browserObject
}
public func makeUIView(context: Self.Context) -> Self.UIViewType {
browserObject
}
public func updateUIView(_ uiView: Self.UIViewType, context: Self.Context) {
//
}
}
struct WebBrowser: View {
@ObservedObject var browser = SUIWebBrowserObject()
init(address: String) {
guard let a = address.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else { return }
guard let u = URL(string: a) else { return }
browser.load(URLRequest(url: u))
}
func ItemImage(systemName: String) -> some View {
Image(systemName: systemName)
.imageScale(.large).aspectRatio(contentMode: .fit)
.frame(width: 32, height: 32)
}
var Title: Text {
Text(verbatim: browser.url?.absoluteString.removingPercentEncoding ?? "")
}
var LItems: some View {
HStack {
Button(action: {
self.browser.goBack()
}) {
ItemImage(systemName: "chevron.left")
}.disabled(!browser.canGoBack)
}
}
var TItems: some View {
HStack {
Button(action: {
if self.browser.isLoading {
self.browser.stopLoading()
} else {
self.browser.reload()
}
}) {
ItemImage(systemName: browser.isLoading
? "xmark"
: "arrow.clockwise"
)
}
}
}
var body: some View {
NavigationView {
SUIWebBrowserView(browserObject: browser)
.navigationBarTitle(Title, displayMode: .inline)
.navigationBarItems(leading: LItems, trailing: TItems)
}.navigationViewStyle(StackNavigationViewStyle())
}
}
struct ContentView: View {
var body: some View {
WebBrowser(address: "https://www.apple.com/jp/")
}
}
WKWebViewをObservableObject化したSUIWebBrowserObject
と、そのビューワーとなるSUIWebBrowserView
を使って自由なUIのカスタムウェブブラウザを簡単に作れるようになった。