0

I am trying to add the back and forward button in the swiftui but the buttons do not work. The URL comes from a firebase. I followed this question How to access goBack and goForward via UIViewRepresentable. If anyone help me, I am very thankful to you. Here is the source code

import SwiftUI
import WebKit
import Firebase

struct WebView: View {

    @State var websiteURL: String
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>


    var body: some View {
        ZStack{
            Color.init(red: 172/255, green: 198/255, blue: 224/255).edgesIgnoringSafeArea(.all)
            VStack{
                Button(action: {
                    self.presentationMode.wrappedValue.dismiss()
                }) {
                    Image("back").renderingMode(.original).frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 60, alignment: .leading).padding()
                }

                Webview(web: nil, req: URLRequest(url: URL(string: websiteURL)!))
                HStack{
                    Button(action: {
                        //go to back
                        Webview(web: nil, req: URLRequest(url: URL(string: websiteURL)!)).goBack()
                    }) {

                        Image(systemName: "arrow.left").foregroundColor(.black)
                    }
                    Spacer()
                    Button(action: {
                       // go forwared
                        Webview(web: nil, req: URLRequest(url: URL(string: websiteURL)!)).goForward()
                    }) {

                        Image(systemName: "arrow.right").foregroundColor(.black)
                    }
                }.padding([.leading,.trailing],20)
            }.navigationBarTitle("")
           .navigationBarHidden(true)
        }.onAppear{
            self.loadURL()

        }

    }
    func loadURL(){
           //For Admin
           let rootRef = Database.database().reference().child("Admin").child(websiteURL)

           rootRef.observeSingleEvent(of: .value, with: { (snapshot) in
             // Get user value
             let value = snapshot.value as? NSDictionary

               let getURL:String = value?["value"] as? String ?? ""
            self.websiteURL=getURL


             // ...
             }) { (error) in
               print(error.localizedDescription)
           }
       }
}

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

struct WebView_Previews: PreviewProvider {
    static var previews: some View {
        WebView(websiteURL: "")
    }
}
Muhammad Farooq
  • 263
  • 3
  • 10
  • seems to me, you create 3 different Webviews, starting afresh at a particular page. goBack() and goForward() to what? There are no previous or forward pages to go to. – workingdog support Ukraine Jun 08 '20 at 03:33
  • I create Webview struct which creates the webview and returns it. The WebView is the main view where I call the Webview and display it. The "Webview" and "WebView" both are different. – Muhammad Farooq Jun 08 '20 at 05:01
  • I fetch the URL from the firebase. The goBack() and goForward in the WebView does not work like Webview(web: nil, req: URLRequest(url: URL(string: websiteURL)!)).goBack(). – Muhammad Farooq Jun 08 '20 at 05:02

1 Answers1

0

I stand by my comment, you create 3 different Webview. This is one way to make it work. Copy and paste this code and let me know if that works for you.

import SwiftUI
import WebKit
import Firebase


struct WebView: View {

@State var websiteURL: String

@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

let websiteView = Webview()

var body: some View {
    ZStack{
        Color.init(red: 172/255, green: 198/255, blue: 224/255).edgesIgnoringSafeArea(.all)
        VStack{
            Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }) {
                Image("back").renderingMode(.original).frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 60, alignment: .leading).padding()
            }
            self.websiteView
            HStack{
                Button(action: {
                    // go to back
                    self.websiteView.webview.goBack()
                }) {
                    Image(systemName: "arrow.left").foregroundColor(.black)
                }
                Spacer()
                Button(action: {
                    // go forwared
                    self.websiteView.webview.goForward()
                }) {
                    Image(systemName: "arrow.right").foregroundColor(.black)
                }
            }.padding([.leading,.trailing],20)
        }.navigationBarTitle("")
            .navigationBarHidden(true)
    }.onAppear{
        self.loadURL()
    }
}

func loadURL() {
       //For Admin
       let rootRef = Database.database().reference().child("Admin").child(websiteURL)

       rootRef.observeSingleEvent(of: .value, with: { (snapshot) in
         // Get user value
         let value = snapshot.value as? NSDictionary

        let getURL:String = value?["value"] as? String ?? ""
        self.websiteURL = getURL

        // new code <-----
        self.websiteView.loadRequest(request: URLRequest(url: URL(string: self.websiteURL)!))  

         // ...
         }) { (error) in
           print(error.localizedDescription)
       }
   }    
}


struct Webview : UIViewRepresentable {

@State var request: URLRequest?

let webview = WKWebView()

func makeUIView(context: Context) -> WKWebView  {
    return webview
}

func updateUIView(_ uiView: WKWebView, context: Context) {
    if request != nil { uiView.load(request!) }
}

func loadRequest(request: URLRequest) {
    self.request = request
    webview.load(request)
}

func goBack(){
    webview.goBack()
}

func goForward(){
    webview.goForward()
}
}