SwiftUI:在 ScrollView 中显示 HTML 文本

问题描述

我正在尝试在我制作的应用程序中显示一些 HTML 文本,但我无法让它正常工作。 问题是包含文本的视图总是以一行的高度显示,即使它被包裹在 ScrollView 中。在截图中,你们可以看到ScrollView可以工作,但原始尺寸很小。

enter image description here

代码是:

let testBook = Book(id: UUID(),name: "Name",author: "Author",genre: "Error",page: "0",total: "77")

public enum AppGroup: String {
  case Livre = "group.com.identifier"

  public var containerURL: URL {
    switch self {
    case .Livre:
      return FileManager.default.containerURL(
      forSecurityApplicationGroupIdentifier: self.rawValue)!
    }
  }
}

struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(),book: testBook)
    }

    func getSnapshot(in context: Context,completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(),book: testBook)
        completion(entry)
    }

    func getTimeline(in context: Context,completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []
            
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .hour,value: hourOffset,to: currentDate)!
            let books: [Book] = self.load("list")
            let entry = SimpleEntry(date: entryDate,book: books.randomElement() ?? testBook)
            entries.append(entry)
        }
            
        let timeline = Timeline(entries: entries,policy: .atEnd)
        completion(timeline)
        
    
    }
    
    func load<T: Decodable>(_ filename: String) -> T {
        let groupDirectory = AppGroup.Livre.containerURL
        let groupURL = groupDirectory
            .appendingPathComponent(filename)
            .appendingPathExtension("json")

        return try! JSONDecoder().decode(T.self,from: Data(contentsOf: groupURL))
    }
}

我也尝试使用 GeometryReader 来确定 ScrollView 的大小,但也没有成功。

有什么办法可以让这看起来正常、漂亮、可滚动且文字大小合适?

非常感谢!

编辑:在@RajaKishan 的回答之后,这就是它的样子(您可以看到内容被截断):

enter image description here

解决方法

由于 WKWebView 已经滚动并且您也被包裹在滚动视图中,因此父滚动视图无法获得正确的大小。 您必须禁用 WKWebView 滚动。另外,用webview绑定size,更新webview的frame。

这是可能的演示。

struct AttributedText: UIViewRepresentable {
    let htmlContent: String
    @Binding var size: CGSize
    
    private let webView = WKWebView()
    var sizeObserver: NSKeyValueObservation?
    
    func makeUIView(context: Context) -> WKWebView {
        webView.scrollView.isScrollEnabled = false //<-- Here
        webView.navigationDelegate = context.coordinator
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView,context: Context) {
        uiView.loadHTMLString(htmlContent,baseURL: nil)
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject,WKNavigationDelegate {
        let parent: AttributedText
        var sizeObserver: NSKeyValueObservation?
        
        init(parent: AttributedText) {
            self.parent = parent
            sizeObserver = parent.webView.scrollView.observe(\.contentSize,options: [.new],changeHandler: { (object,change) in
                parent.size = change.newValue ?? .zero
            })
        }
    }
}

查看

@State private var size: CGSize = .zero

var body: some View{
    ScrollView {
        AttributedText(htmlContent: "<h1>This is HTML String</h1>",size: $size)
            .frame(minWidth: 0,maxWidth: .infinity,minHeight: 0,idealHeight: size.height,maxHeight: .infinity)
    }.frame(minWidth: 0,maxHeight: .infinity)
}