swift - 如何在 SwiftUI WKWebView 中实现 WKUIDelegate?
问题描述
我正在 Xcode v11 上创建一个 Web 应用程序,并且在实现 WKUIDelegate 以显示 Javascript 警报并在 Web 应用程序上正确确认时遇到问题。
我在 ContentView.swift 上有一个非常简单的 webview 应用程序,其中包含以下代码,但不确定如何WKUIDelegate
使用此代码正确实现。
import SwiftUI
import WebKit
struct Webview : UIViewRepresentable {
let request: URLRequest
var webview: WKWebView?
init(web: WKWebView?, req: URLRequest) {
self.webview = WKWebView()
self.request = req
}
func makeUIView(context: Context) -> WKWebView {
return webview!
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.load(request)
}
func goBack(){
webview?.goBack()
}
func goForward(){
webview?.goForward()
}
func reload(){
webview?.reload()
}
}
struct ContentView: View {
let webview = Webview(web: nil, req: URLRequest(url: URL(string: "https://google.com")!))
var body: some View {
VStack {
webview
HStack() {
Button(action: {
self.webview.goBack()
}){
Image(systemName: "chevron.left")
}.padding(32)
Button(action: {
self.webview.reload()
}){
Image(systemName: "arrow.clockwise")
}.padding(32)
Button(action: {
self.webview.goForward()
}){
Image(systemName: "chevron.right")
}.padding(32)
}.frame(height: 32)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
实现WKUIDelegate
此代码的最佳方法是什么?因此,它将正确显示 Javascript 警报和确认。
解决方案
您需要使用Coordinator
然后符合WKUIDelegate
:
class Coordinator: NSObject, WKUIDelegate {
var parent: Webview
init(_ parent: Webview) {
self.parent = parent
}
// Delegate methods go here
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
// alert functionality goes here
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
然后确保您updateUIView(..)
将设置设置uiDelegate
为context.coordinator
:
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.uiDelegate = context.coordinator
[...]
}
如果你想符合
WKNavigationDelegate
然后符合它并设置navigationDelegate
为context.coordinator
以及。
完整代码在这里:
import SwiftUI
import WebKit
struct Webview : UIViewRepresentable {
let request: URLRequest
var webview: WKWebView?
init(web: WKWebView?, req: URLRequest) {
self.webview = WKWebView()
self.request = req
}
class Coordinator: NSObject, WKUIDelegate {
var parent: Webview
init(_ parent: Webview) {
self.parent = parent
}
// Delegate methods go here
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
// alert functionality goes here
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
return webview!
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.uiDelegate = context.coordinator
uiView.load(request)
}
func goBack(){
webview?.goBack()
}
func goForward(){
webview?.goForward()
}
func reload(){
webview?.reload()
}
}
推荐阅读
- python - 根据另一个属性自动设置一个属性的值并缓存它们以供以后使用
- azure-devops - 在 Azure Devops Pipelines Builds 上的 CI 触发器中排除文件类型
- java - 如何从数组中计算唯一的“模式”?
- python - 将数组列表转换为列表?
- python - 检索选定的记录
- c++ - 有没有办法从两个图像创建一个垫子,同时保持图像的参考
- groovy - 用 groovy 迭代嵌套的 json
- python-3.x - 矩阵只产生一半的预期数据
- jsf - 如果在 jsf 中选中了某些复选框,如何启用我的按钮?
- libgdx - 如何使 ImageButton 在 libgdx 中看起来被按下?