无效的文本高度与HTML属性字符串

huangapple go评论59阅读模式
英文:

Invalid Text height with HTML-Attributed string

问题

extension NSAttributedString {

    convenience init(htmlString: String) throws {
        try self.init(data: Data(htmlString.utf8),
                      options: [
                        .documentType: NSAttributedString.DocumentType.html
                      ],
                      documentAttributes: nil)
    }
}

struct CommentView: View {
    var body: some View {
        comment()
    }

    @ViewBuilder
    private func comment() -> some View {
        let string = try! NSAttributedString(htmlString: "<h1>HEADER</h1>")
        Text(AttributedString(string))
            .background(Color.yellow)
    }
}
英文:

I want to display a simple HTML (&lt;h1&gt;HEADER&lt;/h1&gt;) inside Text using AttributedString. The problem is that it displays with invalid height.

extension NSAttributedString {

    convenience init(htmlString: String) throws {
        try self.init(data: Data(htmlString.utf8),
                      options: [
                        .documentType: NSAttributedString.DocumentType.html
                      ],
                      documentAttributes: nil)
    }
}

struct CommentView: View {
    var body: some View {
        comment()
    }

    @ViewBuilder
    private func comment() -&gt; some View {
        let string = try! NSAttributedString(htmlString: &quot;&lt;h1&gt;HEADER&lt;/h1&gt;&quot;)
        Text(AttributedString(string))
            .background(Color.yellow)
    }
}

the following result:

无效的文本高度与HTML属性字符串

答案1

得分: 1

你所遇到的问题,即HTML属性字符串占用的空间比预期多,可能是由于HTML字符串中的一个或多个元素具有 块级显示行为,比如 &lt;div&gt;&lt;p&gt; 标签。

当在属性字符串中遇到具有块级显示行为的HTML元素时,它将被渲染为一个具有自己一行的块级元素,导致在文本视图中添加额外的垂直空间。这是因为块级元素被设计为占据其父容器的整个宽度,并在元素之后创建新行。

为了避免这个问题,一个解决方案是修改HTML字符串,使用内联元素代替块级元素。例如,可以使用 &lt;span&gt; 标签来包装文本内容。&lt;span&gt; 标签具有内联显示行为,这意味着它不会创建新行,而是会随文本一起流动。

let htmlString = &quot;&lt;span style=\&quot;font-size: 24px;\&quot;&gt;HEADER&lt;/span&gt;&quot;

或者,您可以使用这个修改后的扩展,它首先从HTML字符串中修剪掉前导和尾随的空格和换行符。

extension NSAttributedString {
    func trimmedAttributedString() -&gt; NSAttributedString {
        let nonNewlines = CharacterSet.whitespacesAndNewlines.inverted
        
        // 找到第一个非空格字符和换行符
        let startRange = string.rangeOfCharacter(from: nonNewlines)
        
        // 找到最后一个非空格字符和换行符
        let endRange = string.rangeOfCharacter(from: nonNewlines, options: .backwards)
        guard let startLocation = startRange?.lowerBound, let endLocation = endRange?.lowerBound else {
            return self
        }
        // 根据位置获取范围。这会修剪掉前导和尾随的空格和换行符。
        let range = NSRange(startLocation...endLocation, in: string)
        return attributedSubstring(from: range)
    }
}

结果:

let string = try! NSAttributedString(htmlString: &quot;&lt;h1&gt;HEADER&lt;/h1&gt;&quot;)
Text(AttributedString(string.trimmedAttributedString()))
    .background(Color.yellow)
英文:

The issue you are experiencing where the HTML attributed string takes up more space than expected is likely due to the fact that one or more of the elements in the HTML string has a block display behaviour, such as a &lt;div&gt; or &lt;p&gt; tag.

When an HTML element with a block display behavior is encountered in an attributed string, it will be rendered as a block-level element with its own line, causing additional vertical space to be added to the text view. This is because block-level elements are designed to take up the full width of their parent container and create a new line after the element.

To avoid this issue, one solution would be to modify the HTML string to use inline elements instead of block-level elements. For example, instead of using a &lt;div&gt; or &lt;p&gt; tag, you can use a &lt;span&gt; tag to wrap the text content. The &lt;span&gt; tag has an inline display behavior, which means it will not create a new line and will instead flow with the text around it.

let htmlString = &quot;&lt;span style=\&quot;font-size: 24px;\&quot;&gt;HEADER&lt;/span&gt;&quot;

Or you can use this modified extension, which first trim the leading and trailing whitespaces and newline characters from the HTML string.

extension NSAttributedString {
    func trimmedAttributedString() -&gt; NSAttributedString {
        let nonNewlines = CharacterSet.whitespacesAndNewlines.inverted
        
        // Find first non-whitespace character and new line character
        let startRange = string.rangeOfCharacter(from: nonNewlines)
        
        // Find last non-whitespace character and new line character.
        let endRange = string.rangeOfCharacter(from: nonNewlines, options: .backwards)
        guard let startLocation = startRange?.lowerBound, let endLocation = endRange?.lowerBound else {
            return self
        }
        // Getting range out of locations. This trim out leading and trailing whitespaces and new line characters.
        let range = NSRange(startLocation...endLocation, in: string)
        return attributedSubstring(from: range)
    }
}

Results:

    let string = try! NSAttributedString(htmlString: &quot;&lt;h1&gt;HEADER&lt;/h1&gt;&quot;)
    Text(AttributedString(string.trimmedAttributedString()))
        .background(Color.yellow)

无效的文本高度与HTML属性字符串

huangapple
  • 本文由 发表于 2023年3月9日 17:05:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75682421.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定