WebView in Pages #21

Open
opened 2025-10-14 17:31:36 -06:00 by navan · 0 comments
Owner

Originally created by @halilyuce on 4/12/2020

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

*Originally created by @halilyuce on 4/12/2020* 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](https://user-images.githubusercontent.com/29376592/79076559-c4e5f480-7d03-11ea-9c81-e641c529033d.png) Second Page ![image](https://user-images.githubusercontent.com/29376592/79076568-d62f0100-7d03-11ea-9765-2feb9bcf046a.png)
Sign in to join this conversation.
No labels
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github/Pages#21
No description provided.