iOS: 在 UIViewRepresentable 和 View 之间进行函数调用,SwiftUI
iOS: Make function calls between UIViewRepresentable and View both ways, SwiftUI
我正在构建一个应用程序,其中一个页面具有 Web 视图。目前该页面有一个可表示的 webview 和一个视图。使用 UIViewControllerRepresentable 将 Webview 带到视图中。我首先想知道当我点击登录按钮时如何调用 LoginWebview 中的函数,其次反之亦然,我如何从 LoginWebview 调用 LoginView 中的函数。我目前已进行设置,因此当我单击登录时,它会切换导致 updateUIView 触发的状态,但我如何在其中调用自定义函数?反之亦然
对上面的冗长描述表示歉意,如果这是一个愚蠢的问题
谢谢:)
登录视图:
import SwiftUI
import WebKit
struct LoginView: View {
@State public var email: String = ""
@State public var password: String = ""
let verticalPaddingForForm = 40
@State private var willMoveToNextScreen = true
@Binding var isLoggedIn: Bool
@State var showJSAlert = false
var body: some View {
LoginWebview(testdo: self.showJSAlert)
ZStack {
Color(red: 20/225.0 ,green: 22/225.0 , blue: 25/225.0)
VStack(alignment: .leading, spacing: 0) {
Image("logo")
.resizable()
.scaledToFit()
.padding(.top, 150)
.padding()
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
.ignoresSafeArea(.all)
VStack(spacing: CGFloat(verticalPaddingForForm)) {
VStack {
TextField("Email", text: $email)
.padding(.horizontal, 15).padding(.top, 50)
Divider()
.padding(.horizontal, 15)
SecureField("Password", text: $password)
.padding(.horizontal, 15).padding(.top, 20)
Divider()
.padding(.horizontal, 15)
}
.background(Color(.white))
Button(action: {
//Calls login webview and triggers update that calls the js
self.showJSAlert.toggle()
}) {
Text("Login")
.padding()
.font(.system(size: 20))
}
.background(Color.black)
.foregroundColor(Color.white)
.cornerRadius(10)
.padding(.top, 0)
.padding(.bottom, 20)
}
.padding(.horizontal, CGFloat(verticalPaddingForForm))
.background(Color(.white))
VStack{
Spacer()
Button(action: {
}) {
Text("Register")
.padding()
.font(.system(size: 40))
}
.background(Color(red: 20/225.0 ,green: 22/225.0 , blue: 25/225.0))
.foregroundColor(Color.white)
.cornerRadius(10)
.padding()
}
}.ignoresSafeArea()
};
登录网页视图:
import SwiftUI
import WebKit
struct LoginWebview: UIViewRepresentable {
var testdo = false
func makeUIView(context: UIViewRepresentableContext<LoginWebview>) -> WKWebView {
let preferences = WKPreferences()
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let userContentController = WKUserContentController()
userContentController.add(context.coordinator, name:"observer")
configuration.userContentController = userContentController
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.navigationDelegate = context.coordinator
let url = URL(string: "https://www.google.co.uk")!
webView.load(URLRequest(url: url))
return webView
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<LoginWebview>) {
print(testdo)
print("Controller")
uiView.evaluateJavaScript("sendComment();")
print(UserDefaults.standard.string(forKey: "Token") ?? "")
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func printstuff() {
print("printstuff")
}
typealias UIViewType = WKWebView
}
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var control: LoginWebview
init(_ control: LoginWebview) {
self.control = control
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
showAlert(body: message.body)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func sendjs(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func showAlert(body: Any) {
print("working")
}
}
您可以使用计算 属性 和闭包进行回调。
这是示例代码。
struct LoginView: View {
// Other code
// Webview var
private var webView: LoginWebview {
LoginWebview(testdo: self.showJSAlert) {
// Here you will get the call back
print("Callback")
}
}
var body: some View {
webView // <-- Here
// Other Code
以及按钮操作
Button(action: {
//Calls login webview and triggers update that calls the js
self.showJSAlert.toggle()
// Access your function
self.webView.printstuff()
}) {
Text("Login")
.padding()
.font(.system(size: 20))
}
并且在LoginWebview
struct LoginWebview: UIViewRepresentable {
var testdo = false
var callBack: (() -> Void)? = nil
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
// Other code
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.control.callBack?() // < Example for calling callback
}
// Other code
}
我正在构建一个应用程序,其中一个页面具有 Web 视图。目前该页面有一个可表示的 webview 和一个视图。使用 UIViewControllerRepresentable 将 Webview 带到视图中。我首先想知道当我点击登录按钮时如何调用 LoginWebview 中的函数,其次反之亦然,我如何从 LoginWebview 调用 LoginView 中的函数。我目前已进行设置,因此当我单击登录时,它会切换导致 updateUIView 触发的状态,但我如何在其中调用自定义函数?反之亦然
对上面的冗长描述表示歉意,如果这是一个愚蠢的问题
谢谢:)
登录视图:
import SwiftUI
import WebKit
struct LoginView: View {
@State public var email: String = ""
@State public var password: String = ""
let verticalPaddingForForm = 40
@State private var willMoveToNextScreen = true
@Binding var isLoggedIn: Bool
@State var showJSAlert = false
var body: some View {
LoginWebview(testdo: self.showJSAlert)
ZStack {
Color(red: 20/225.0 ,green: 22/225.0 , blue: 25/225.0)
VStack(alignment: .leading, spacing: 0) {
Image("logo")
.resizable()
.scaledToFit()
.padding(.top, 150)
.padding()
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
.ignoresSafeArea(.all)
VStack(spacing: CGFloat(verticalPaddingForForm)) {
VStack {
TextField("Email", text: $email)
.padding(.horizontal, 15).padding(.top, 50)
Divider()
.padding(.horizontal, 15)
SecureField("Password", text: $password)
.padding(.horizontal, 15).padding(.top, 20)
Divider()
.padding(.horizontal, 15)
}
.background(Color(.white))
Button(action: {
//Calls login webview and triggers update that calls the js
self.showJSAlert.toggle()
}) {
Text("Login")
.padding()
.font(.system(size: 20))
}
.background(Color.black)
.foregroundColor(Color.white)
.cornerRadius(10)
.padding(.top, 0)
.padding(.bottom, 20)
}
.padding(.horizontal, CGFloat(verticalPaddingForForm))
.background(Color(.white))
VStack{
Spacer()
Button(action: {
}) {
Text("Register")
.padding()
.font(.system(size: 40))
}
.background(Color(red: 20/225.0 ,green: 22/225.0 , blue: 25/225.0))
.foregroundColor(Color.white)
.cornerRadius(10)
.padding()
}
}.ignoresSafeArea()
};
登录网页视图:
import SwiftUI
import WebKit
struct LoginWebview: UIViewRepresentable {
var testdo = false
func makeUIView(context: UIViewRepresentableContext<LoginWebview>) -> WKWebView {
let preferences = WKPreferences()
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
let userContentController = WKUserContentController()
userContentController.add(context.coordinator, name:"observer")
configuration.userContentController = userContentController
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.navigationDelegate = context.coordinator
let url = URL(string: "https://www.google.co.uk")!
webView.load(URLRequest(url: url))
return webView
}
func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<LoginWebview>) {
print(testdo)
print("Controller")
uiView.evaluateJavaScript("sendComment();")
print(UserDefaults.standard.string(forKey: "Token") ?? "")
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func printstuff() {
print("printstuff")
}
typealias UIViewType = WKWebView
}
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
var control: LoginWebview
init(_ control: LoginWebview) {
self.control = control
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
showAlert(body: message.body)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func sendjs(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
func showAlert(body: Any) {
print("working")
}
}
您可以使用计算 属性 和闭包进行回调。
这是示例代码。
struct LoginView: View {
// Other code
// Webview var
private var webView: LoginWebview {
LoginWebview(testdo: self.showJSAlert) {
// Here you will get the call back
print("Callback")
}
}
var body: some View {
webView // <-- Here
// Other Code
以及按钮操作
Button(action: {
//Calls login webview and triggers update that calls the js
self.showJSAlert.toggle()
// Access your function
self.webView.printstuff()
}) {
Text("Login")
.padding()
.font(.system(size: 20))
}
并且在LoginWebview
struct LoginWebview: UIViewRepresentable {
var testdo = false
var callBack: (() -> Void)? = nil
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
// Other code
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.control.callBack?() // < Example for calling callback
}
// Other code
}