使用AttributedString在Text中显示HTML时高度异常问题
解决SwiftUI Text显示HTML转AttributedString高度异常的问题
你遇到的问题根源在于:用HTML转NSAttributedString时,WebKit会自动应用默认网页样式(比如body的默认边距、h1标签的上下间距),这些样式被转换成NSAttributedString的段落属性后,SwiftUI的Text会严格遵循,导致出现多余的上下空白。
下面是两种有效的解决办法:
方法一:修改HTML内容,清除默认样式
直接在HTML代码中添加样式重置,把默认的margin和padding清零,从源头去掉多余空白:
extension NSAttributedString { convenience init(htmlString: String) throws { // 用清除默认样式的容器包裹原始HTML let styledHtml = """ <div style="margin:0; padding:0;"> \(htmlString) </div> """ try self.init(data: Data(styledHtml.utf8), options: [ .documentType: NSAttributedString.DocumentType.html ], documentAttributes: nil) } } struct CommentView: View { var body: some View { comment() } @ViewBuilder private func comment() -> some View { // 给h1标签也加上清零样式 let string = try! NSAttributedString(htmlString: "<h1 style='margin:0; padding:0;'>HEADER</h1>") Text(AttributedString(string)) .background(Color.yellow) } }
方法二:修改NSAttributedString的段落属性
如果不想改动HTML内容,可以在转换完成后,遍历NSAttributedString重置段落样式里的多余间距:
extension NSAttributedString { convenience init(htmlString: String) throws { try self.init(data: Data(htmlString.utf8), options: [ .documentType: NSAttributedString.DocumentType.html ], documentAttributes: nil) } // 清除多余的段落间距属性 func removingExtraParagraphSpacing() -> NSAttributedString { let mutableString = NSMutableAttributedString(attributedString: self) mutableString.enumerateAttribute(.paragraphStyle, in: NSRange(location: 0, length: mutableString.length)) { value, range, _ in if let style = value as? NSParagraphStyle { let newStyle = NSMutableParagraphStyle() newStyle.setParagraphStyle(style) // 重置上下段落间距和行间距 newStyle.paragraphSpacing = 0 newStyle.paragraphSpacingBefore = 0 newStyle.lineSpacing = 0 mutableString.addAttribute(.paragraphStyle, value: newStyle, range: range) } } return mutableString } } struct CommentView: View { var body: some View { comment() } @ViewBuilder private func comment() -> some View { let string = try! NSAttributedString(htmlString: "<h1>HEADER</h1>").removingExtraParagraphSpacing() Text(AttributedString(string)) .background(Color.yellow) } }
内容的提问来源于stack exchange,提问作者Nikita Ermolenko
相关产品推荐
相关产品推荐

