问题描述
我收到来自 MathJax
响应的 String
API
,需要在 WKWebView
中的 SwiftUI
中显示。这是一个示例 String
"<img alt=\"\" height=\"2305\" src=\"https:\/\/s3-us-west-2.amazonaws.com\/infinitestudent-images\/ckeditor_assets\/pictures\/37732\/content_types_of_combustion.jpg\" width=\"800\" \/>"
这是我试过的代码:
import SwiftUI
import WebKit
struct Model: Codable {
var mathjaxBody: String?
var answer: Answer
}
struct MathJaxView: View {
let model: Model
var body: some View {
ScrollView {
AnswerSectionView(answer: model.answer)
HTMLView(htmlString: model.mathjaxBody)
.frame(minWidth: 100,maxWidth: .infinity,minHeight: 100,maxHeight: .infinity)
}
}
}
struct HTMLView: UIViewRepresentable {
var htmlString: String?
func makeUIView(context: Context) -> WKWebView {
WKWebView(frame: .zero)
}
func updateUIView(_ uiView: WKWebView,context: Context) {
guard let string = htmlString else { return }
uiView.loadHTMLString(string,baseURL: nil)
}
}
它需要在一个 ScrollView
中,上面有一些不同的细节,在 ScrollView
中正确显示。但是,HTMLView
没有出现。我尝试添加 .frame(minWidth: 100,maxHeight: .infinity)
但仍然没有显示。
解决方法
解决方案是简单地通过 evaluateJavaScript("document.body.scrollHeight")
方法计算所需的高度,然后使用其他一些方法将其应用到 WebView
组件。
struct WebView: UIViewRepresentable {
var htmlString: String?
@EnvironmentObject var viewModel: WebViewModel
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView(frame: .zero)
webView.backgroundColor = .clear
webView.navigationDelegate = context.coordinator
webView.scrollView.isScrollEnabled = false
return webView
}
func updateUIView(_ uiView: WKWebView,context: Context) {
guard let string = htmlString else { return }
uiView.loadHTMLString(string,baseURL: nil)
}
class Coordinator: NSObject,WKNavigationDelegate {
private var viewModel: WebViewModel
init(viewModel: WebViewModel) {
self.viewModel = viewModel
}
func webView(_ webView: WKWebView,didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("document.readyState") { (complete,error) in
if complete != nil {
webView.evaluateJavaScript("document.body.scrollHeight") { (height,error) in
if let height = height as? CGFloat,self.viewModel.contentHeight == 0 {
self.viewModel.contentHeight = height * 0.4
}
}
}
}
}
}
func makeCoordinator() -> Coordinator {
Coordinator(viewModel: viewModel)
}
}
class WebViewModel: ObservableObject {
@Published var contentHeight: CGFloat = 0
}
struct MathJaxView: View {
let model: Model
var body: some View {
ScrollView {
AnswerSectionView(answer: model.answer)
WebView(htmlString: model.mathjaxBody)
.environmentObject(webViewModel)
.frame(height: webViewModel.contentHeight)
.frame(maxWidth: .infinity)
.fixedSize(horizontal: false,vertical: true)
}
}
}