在 userContentController 中启动/更新视图 - 功能
Start / update View in userContentController - Function
我尝试通过单击按钮在 WKWebview 的帮助下启动第二个视图。
它也有效。我在函数 userContentController 中得到一个回调。如何通过此功能在应用程序中启动新视图。
struct MyWebView: UIViewRepresentable {
var webPageURL = "https://google.de"
func updateUIView(_ uiView: WKWebView, context: Context) {
let myURL = URL(string:webPageURL)
let myRequest = URLRequest(url: myURL!)
uiView.load(myRequest)
}
func makeUIView(context: Context) -> WKWebView {
let webConfiguration = WKWebViewConfiguration()
let wkcontentController = WKUserContentController()
wkcontentController.add(context.coordinator, name: "doStuffMessageHandler")
webConfiguration.userContentController = wkcontentController
let webView = WKWebView(frame: .zero,configuration: webConfiguration)
context.coordinator.parent = webView // inject as weak
return webView
}
func makeCoordinator() -> ContentController {
ContentController() // let handler be a coordinator
}
}
class ContentController: NSObject, WKScriptMessageHandler {
weak var parent: WKWebView? // weak to avoid reference cycling
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
{
if message.name == "doStuffMessageHandler"
{
print(message.body)
}
}
}
struct MyWebView_Previews: PreviewProvider {
static var previews: some View {
MyWebView()
}
}
可能的解决方案是使用通知(允许保持这些组件独立)。
extension Notification.Name {
static let didReceiveMessage = Notification.Name("didReceiveMessage")
}
class ContentController: NSObject, WKScriptMessageHandler {
weak var parent: WKWebView? // weak to avoid reference cycling
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
{
if message.name == "doStuffMessageHandler"
{
NotificationCenter.default.post(name: .didReceiveMessage, object: message.body)
}
}
}
struct DemoHandleMessage: View {
@State private var showMessage = false
@State private var message: String? = nil
var body: some View {
VStack {
if showMessage {
// switch back via bound flag to showMessage state
MessageView(text: message, dismiss: $showMessage)
} else {
MyWebView()
}
}.onReceive(NotificationCenter.default.publisher(for: .didReceiveMessage)) { notification in
self.message = notification.object as? String
self.showMessage = true
}
}
}
我尝试通过单击按钮在 WKWebview 的帮助下启动第二个视图。 它也有效。我在函数 userContentController 中得到一个回调。如何通过此功能在应用程序中启动新视图。
struct MyWebView: UIViewRepresentable {
var webPageURL = "https://google.de"
func updateUIView(_ uiView: WKWebView, context: Context) {
let myURL = URL(string:webPageURL)
let myRequest = URLRequest(url: myURL!)
uiView.load(myRequest)
}
func makeUIView(context: Context) -> WKWebView {
let webConfiguration = WKWebViewConfiguration()
let wkcontentController = WKUserContentController()
wkcontentController.add(context.coordinator, name: "doStuffMessageHandler")
webConfiguration.userContentController = wkcontentController
let webView = WKWebView(frame: .zero,configuration: webConfiguration)
context.coordinator.parent = webView // inject as weak
return webView
}
func makeCoordinator() -> ContentController {
ContentController() // let handler be a coordinator
}
}
class ContentController: NSObject, WKScriptMessageHandler {
weak var parent: WKWebView? // weak to avoid reference cycling
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
{
if message.name == "doStuffMessageHandler"
{
print(message.body)
}
}
}
struct MyWebView_Previews: PreviewProvider {
static var previews: some View {
MyWebView()
}
}
可能的解决方案是使用通知(允许保持这些组件独立)。
extension Notification.Name {
static let didReceiveMessage = Notification.Name("didReceiveMessage")
}
class ContentController: NSObject, WKScriptMessageHandler {
weak var parent: WKWebView? // weak to avoid reference cycling
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
{
if message.name == "doStuffMessageHandler"
{
NotificationCenter.default.post(name: .didReceiveMessage, object: message.body)
}
}
}
struct DemoHandleMessage: View {
@State private var showMessage = false
@State private var message: String? = nil
var body: some View {
VStack {
if showMessage {
// switch back via bound flag to showMessage state
MessageView(text: message, dismiss: $showMessage)
} else {
MyWebView()
}
}.onReceive(NotificationCenter.default.publisher(for: .didReceiveMessage)) { notification in
self.message = notification.object as? String
self.showMessage = true
}
}
}