SwiftUI:在 ScrollView 中显示 HTML 文本
SwiftUI: Showing HTML text inside a ScrollView
我试图在我正在制作的应用程序中显示一些 HTML 文本,但我无法让它正常工作。
问题是包含文本的视图总是显示只有一行的高度,即使它被包裹在 ScrollView 中。在截图中,大家可以看到ScrollView是可以工作的,但是原来的尺寸很小。
密码是:
ScrollView {
GeometryReader { proxy in
AttributedText(htmlContent: job.description)
.frame(height: proxy.size.height, alignment: .center)
}
}
struct AttributedText: UIViewRepresentable {
let htmlContent: String
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.loadHTMLString(htmlContent, baseURL: nil)
}
}
struct AttributedText_Previews: PreviewProvider {
static var previews: some View {
AttributedText(htmlContent: "<h1>This is HTML String</h1>")
}
}
我也尝试过使用 GeometryReader 来确定 ScrollView 的大小,但也不成功。
有什么方法可以使它看起来正常、美观、可滚动并具有适当的文本大小?
非常感谢!
编辑:在@RajaKishan 的回答后,它是这样的(你可以看到内容被截断):
由于 WKWebView
已经滚动并且您也被包裹在滚动视图中,因此父滚动视图无法获得正确的大小。
您必须禁用 WKWebView
滚动。另外,将size与webview绑定,并更新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, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
我试图在我正在制作的应用程序中显示一些 HTML 文本,但我无法让它正常工作。 问题是包含文本的视图总是显示只有一行的高度,即使它被包裹在 ScrollView 中。在截图中,大家可以看到ScrollView是可以工作的,但是原来的尺寸很小。
密码是:
ScrollView {
GeometryReader { proxy in
AttributedText(htmlContent: job.description)
.frame(height: proxy.size.height, alignment: .center)
}
}
struct AttributedText: UIViewRepresentable {
let htmlContent: String
func makeUIView(context: Context) -> WKWebView {
return WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
uiView.loadHTMLString(htmlContent, baseURL: nil)
}
}
struct AttributedText_Previews: PreviewProvider {
static var previews: some View {
AttributedText(htmlContent: "<h1>This is HTML String</h1>")
}
}
我也尝试过使用 GeometryReader 来确定 ScrollView 的大小,但也不成功。
有什么方法可以使它看起来正常、美观、可滚动并具有适当的文本大小?
非常感谢!
编辑:在@RajaKishan 的回答后,它是这样的(你可以看到内容被截断):
由于 WKWebView
已经滚动并且您也被包裹在滚动视图中,因此父滚动视图无法获得正确的大小。
您必须禁用 WKWebView
滚动。另外,将size与webview绑定,并更新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, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}