简体   繁体   English

iOS:在 UIViewRepresentable 和 View 之间进行 function 调用,SwiftUI

[英]iOS: Make function calls between UIViewRepresentable and View both ways, SwiftUI

I am building an application where one of the pages has a webview.我正在构建一个应用程序,其中一个页面具有 webview。 Currently the page has a the webview representable and a view.目前该页面有一个 webview 表示和一个视图。 Webview is brought to the view using the UIViewControllerRepresentable.使用 UIViewControllerRepresentable 将 Webview 带到视图中。 I am wondering firstly how when I tap the login button can I call a function inside the LoginWebview, and also secondly vice versa, how can I call a function in the LoginView from the LoginWebview.我首先想知道当我点击登录按钮时如何在 LoginWebview 中调用 function,其次反之亦然,如何从 LoginWebview 在 LoginView 中调用 function。 I currently have the set up so that when I click login it toggles the states which causes the updateUIView to trigger but how can I call a custom made function in there?我目前已经进行了设置,因此当我单击登录时,它会切换导致 updateUIView 触发的状态,但是我如何在其中调用定制的 function? And vice versa反之亦然

Apologies for the long description above and if this a stupid question为上面的冗长描述道歉,如果这是一个愚蠢的问题

Thanks:)谢谢:)

LoginView:登录视图:

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()
    };

LoginWebview:登录网页视图:

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

You can use computed property and closure for a callback.您可以将计算属性和闭包用于回调。

Here is the example code.这是示例代码。

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

And for button action对于按钮动作

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

And in LoginWebview并在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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 UIViewRepresentable 隐藏在 SwiftUI 视图后面 - UIViewRepresentable hidden behind SwiftUI View 在 UIViewRepresentable 和 SwiftUI 之间传递数据 - Pass data between UIViewRepresentable and SwiftUI 从 SwiftUI 中的 UIViewRepresentable 呈现视图 - Present view from UIViewRepresentable in SwiftUI SwiftUI:如何从 UIViewRepresentable 导航到 SwiftUI 视图 - SwiftUI: How to navigate from UIViewRepresentable to SwiftUI View SwiftUI - 从 UITableView (UIViewRepresentable) 导航到 View - SwiftUI - Navigate from UITableView (UIViewRepresentable) to View 无法使 UIViewRepresentable 的 CustomView 在 SwiftUI 中正常工作 - Cannot make CustomView for UIViewRepresentable to work correctly in SwiftUI 如何将 SwiftUI 视图放置在 UIKit (UIViewRepresentable) 视图之上? (错误或错误?) - How to place a SwiftUI view on top of a UIKit (UIViewRepresentable) view? (bug or mistake?) 带有 UIViewRepresentable 的 SwiftUI 自定义文本字段 ObservableObject 和推送视图的问题 - SwiftUI Custom TextField with UIViewRepresentable Issue with ObservableObject and pushed View SwiftUI - 使用 UIViewRepresentable 包装视图以使用 NSMutableAttributedString - SwiftUI - Using UIViewRepresentable to wrap view in order to use NSMutableAttributedString SwiftUI:避免使用 MKMapView+UIViewRepresentable 在 TabView 中重新创建/重新渲染视图 - SwiftUI: avoid recreating/rerendering view in TabView with MKMapView+UIViewRepresentable
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM