项目配置
首先进行项目配置,支持入网
包装webView
首先为了能在Swift UI中使用WebView,应该对其进行包装
struct WebView: NSViewRepresentable {
let webView: WKWebView
func makeNSView(context: Context) -> WKWebView { return webView }
func updateNSView(_ nsView: WKWebView, context: Context) { }
}
实现代理
class WebViewNavigationDelegate: NSObject, WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// TODO
decisionHandler(.allow)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
// TODO
decisionHandler(.allow)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
}
}
自定义webView
观察网页在什么时候需要前进或者后退,这个时候要用ObservableObject来进行包装
class CustomWebView: ObservableObject {
let webView: WKWebView
private let navigationDelegate: WebViewNavigationDelegate
init() {
let configuration = WKWebViewConfiguration()
configuration.websiteDataStore = .nonPersistent()
webView = WKWebView(frame: .zero, configuration: configuration)
navigationDelegate = WebViewNavigationDelegate()
webView.navigationDelegate = navigationDelegate
setupBindings()
}
@Published var urlString: String = "https://www.csdn.net/"
@Published var canGoBack: Bool = false
@Published var canGoForward: Bool = false
@Published var isLoading: Bool = false
private func setupBindings() {
webView.publisher(for: \.canGoBack)
.assign(to: &$canGoBack)
webView.publisher(for: \.canGoForward)
.assign(to: &$canGoForward)
webView.publisher(for: \.isLoading)
.assign(to: &$isLoading)
}
func loadUrl() {
guard let url = URL(string: urlString) else {
return
}
webView.load(URLRequest(url: url))
}
func goForward() {
webView.goForward()
}
func goBack() {
webView.goBack()
}
}
调试
现在,可以将它放到contentView中调试
struct ContentView: View {
@StateObject var model = CustomWebView()
var body: some View {
ZStack(alignment: .bottom) {
Color.black
.ignoresSafeArea()
VStack(spacing: 0) {
HStack(spacing: 10) {
HStack {
TextField("Input an url",
text: $model.urlString)
.disableAutocorrection(true)
.padding(10)
Spacer()
}
.background(Color.white)
.cornerRadius(30)
Button("Go", action: {
model.loadUrl()
})
.foregroundColor(.blue)
.padding(10)
}.padding(10)
ZStack {
WebView(webView: model.webView)
if model.isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
}
}
}
}
.toolbar {
ToolbarItemGroup(placement: .navigation) {
Button(action: {
model.goBack()
}, label: {
Image(systemName: "arrowshape.turn.up.backward")
})
.disabled(!model.canGoBack)
Button(action: {
model.goForward()
}, label: {
Image(systemName: "arrowshape.turn.up.right")
})
.disabled(!model.canGoForward)
Spacer()
}
}
}
}