5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftUIでWebViewを使う(WKWebViewのObservableObject化)

Posted at

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/")
    }
}

75049C07-A975-4E53-9230-7B6EFD503215.jpeg

WKWebViewをObservableObject化したSUIWebBrowserObjectと、そのビューワーとなるSUIWebBrowserViewを使って自由なUIのカスタムウェブブラウザを簡単に作れるようになった。

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?