nachonavarro / Pages

📖 A lightweight, paging view solution for SwiftUI

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WebView in Pages

halilyuce opened this issue · comments

Hello again :)

I want to load each news inside of pages, I am loading Html content in wkwebview and I added it to the inside of pages. When I move to the next page webview height is the same as the previous one, does not load with new height.

What do you recommend to solve this issue ? Thanks in advance :)

WebTest View

import SwiftUI
import Pages

struct WebTest: View {
    
    @ObservedObject var viewModel = NewsVM()
    @State var index: Int = 0
    @State var newID: String = ""
    let screen = UIScreen.main.bounds
    let formatString = "<html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0\"><script type=\"text/javascript\" src=\"https://platform.twitter.com/widgets.js\"></script><style>@media (prefers-color-scheme: dark) { body { background-color: #1c1c1e; color: white; }} img,iframe,blockquote {\n\t\t\tmax-width: \(UIScreen.main.bounds.width - 24);\n\t\t\theight: auto\n\t\t}\n\t\t</style></head><body><span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size:17\">%@</span></body></html>"
    @State private var webViewHeight: CGFloat = .zero
    
    init(id:String) {
        viewModel.fetchNews(id: id)
        self.newID = id
    }
    
    var body: some View {
        Group{
            if self.viewModel.news.count > 0 {
                ModelPages(viewModel.news, currentPage: $index, wrap: false, hasControl: false) { pageIndex, new in
                    ScrollView(.vertical, showsIndicators: false){
                            Text(new.title)
                                .font(.title).fontWeight(.bold)
                                .padding(.horizontal)
                                .fixedSize(horizontal: false, vertical: true)
                            Text("Height: \(self.webViewHeight)").padding()
                            WebView(htmlString: String(format: self.formatString, new.content), dynamicHeight: self.$webViewHeight)
                                .frame(width: self.screen.width - 16, height: self.webViewHeight)
                                .padding(.horizontal, 8)
                        }
                    }
            }else{
                Group{
                    if self.viewModel.error == true{
                        ConnectionError()
                    }else{
                        LoadingView()
                    }
                }
            }
        }
    }
}

WebView

import SwiftUI
import Webkit

struct WebView: UIViewRepresentable {
    var htmlString: String
    @Binding var dynamicHeight: CGFloat
    var webView: WKWebView = WKWebView()
    
    func makeUIView(context: Context) -> WKWebView {
        webView.navigationDelegate = context.coordinator
        webView.scrollView.bounces = false
        webView.backgroundColor = .clear
        if htmlString != context.coordinator.content {
            context.coordinator.content = htmlString
            webView.loadHTMLString(htmlString, baseURL: Bundle.main.bundleURL)
        }
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, WKNavigationDelegate {
        var parent: WebView
        var content = ""

        init(_ parent: WebView) {
            self.parent = parent
        }
        
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
                if complete != nil {
                   webView.evaluateJavaScript("document.documentElement.scrollHeight", completionHandler: { (height, error) in
                        DispatchQueue.main.async{
                            self.parent.dynamicHeight = height as? CGFloat ?? 0
                        }
                    })
                }
            })
        }
    }
}

First content height is true, but the second view still using same height

First Page
image

Second Page
image

Hey! Could you replicate a minimal example of this without the SDWebImageSwiftUI dependency
so I can test this?

@nachonavarro hello, SDWebImage is not needed now :) I found what causes to it. When the previous content height is smaller than the next one, it's working well but when it's bigger than next one it's not changing height value. Interesting but I don't have any idea how can I fix it. I researched it on google and StackOverflow but I could not find any solution for it.