Xcode 14中SwiftUI如何读取JSON文件中的HTML格式文本?
问题描述
我有一个包含HTML样式标记(加粗<b>、斜体<i>等)的JSON文件,需要在SwiftUI的详情页中保留这些格式展示文本。目前已完成JSON数据读取并显示在列表中,点击可跳转至详情页,但始终无法实现保留HTML格式的文本展示。我使用Xcode 14和SwiftUI,搜索过资料及Apple开发者文档都没找到可行方案,应用必须正确显示这些格式,而这在HTML/JS里很容易实现,自己刚接触SwiftUI,不清楚哪里出错了。附上JSON结构和LandmarkDetail视图代码,尝试添加属性时均报错,寻求帮助。
JSON示例
[ { "imageurl": "1.png", "levelLongDesc":"A longer description", "id": "1.", "name": "A name", "page": "Details", "description":"<p><b>E pluribus unum</b></p><b>Instructions.</b> Latin for “Out of many one”, is a motto requested by <i>Pierre Eugene du Simitiere</i> (originally Pierre-Eugène Ducimetière) and found in 1776 on the Seal of the United States, along with Annuit cœptis and Novus ordo seclorum, and adopted by an Act of Congress in 1782.</p><p>", "videoDemo":"myvideo" } ]
现有代码示例
import SwiftUI struct LandmarkDetail: View { var landmark: Landmark @State var Description = AttributedString("") var body: some View { NavigationView{ ScrollView { RectImage(image: landmark.image) .padding(.top, 30) .font(.subheadline) .foregroundColor(.secondary) Divider() Text("\(landmark.name)") Text(landmark.description) .font(.title3) .padding(.horizontal, 20) .onAppear { (addStyling(landmark.description)) } } .padding() }.navigationTitle(landmark.name) .navigationBarTitleDisplayMode(.inline) } private func addStyling(_ htmlString: String) -> NSAttributedString { var resultString = NSAttributedString() var data = Data() // Add the html data/ var in which you stored it data.append(Data(landmark.description.utf8)) // Convert the attributed String do { let attributedString = try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) resultString = attributedString } catch { print(error) } return resultString } }
解决方案
你的核心问题是没有把转换后的富文本赋值给用于展示的变量,且没有正确适配SwiftUI的AttributedString类型。以下是修正后的代码:
import SwiftUI struct LandmarkDetail: View { var landmark: Landmark // 存储转换后的富文本,符合Swift命名规范 @State private var attributedDescription = AttributedString("") var body: some View { NavigationView { ScrollView { RectImage(image: landmark.image) .padding(.top, 30) .font(.subheadline) .foregroundColor(.secondary) Divider() Text(landmark.name) // 直接使用转换后的富文本 Text(attributedDescription) .font(.title3) .padding(.horizontal, 20) } .padding() .navigationTitle(landmark.name) .navigationBarTitleDisplayMode(.inline) // 视图出现时执行转换 .onAppear { convertHtmlToAttributedString() } } } private func convertHtmlToAttributedString() { // 直接将HTML字符串转为Data,简化逻辑 guard let data = landmark.description.data(using: .utf8) else { attributedDescription = AttributedString(landmark.description) return } do { let nsAttributedString = try NSAttributedString( data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil ) // 将UIKit的NSAttributedString转为SwiftUI可用的AttributedString attributedDescription = AttributedString(nsAttributedString) } catch { print("HTML转换失败: \(error.localizedDescription)") // 转换失败时兜底显示原始文本 attributedDescription = AttributedString(landmark.description) } } }
关键修改说明
- 重命名
@State变量为attributedDescription,符合Swift命名规范,专门用于存储转换后的富文本。 - 在
onAppear中调用转换方法,确保视图加载时完成HTML到富文本的转换。 - 展示文本时使用
Text(attributedDescription),直接渲染带格式的内容。 - 简化Data创建逻辑,直接通过
htmlString.data(using: .utf8)获取数据。 - 添加错误兜底逻辑,转换失败时显示原始文本,避免空白。
内容的提问来源于stack exchange,提问作者user1204493
相关产品推荐
相关产品推荐

