Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] lineLimit truncation does not work as expected when markdown content ends with a link #115

Closed
maciesielka opened this issue Jul 27, 2022 · 4 comments

Comments

@maciesielka
Copy link

Build Information

Markdown UI Version: Latest (1.1.1 at time of writing)
Xcode Version: 13.4.1
iOS Simulator: iPhone 13 Pro, iOS 15.5 (reproduces on a physical iPhone 11 Pro Max -- iOS 15.5 as well)

Issue Description

There seems to be an issue with how the lineLimit modifier affects Markdown when the content ends in a link.

In the example below, the intention is to truncate the full body of the markdown at 4 lines.

import MarkdownUI
import SwiftUI

struct ContentView: View {
    var text: String {
        """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. \
        Aenean a dolor at enim varius faucibus. Vivamus eget \
        ultrices lorem, non scelerisque enim.

        [https://www.google.com](https://www.google.com)
        """
    }

    var body: some View {
        Markdown(text)
            .lineLimit(4)
            .truncationMode(.tail)
            .padding(16)
    }
}

This renders as below, with the non-truncated version that just removes the lineLimit modifier shown at right:

Truncated Non-truncated
Screen Shot 2022-07-27 at 12 24 48 PM Screen Shot 2022-07-27 at 12 23 09 PM

You can see that the link that is last in the markdown text is shown in both versions, despite being the last line of content overall and not the last line you'd expect to see of truncated content.

The strangeness worsens applying line-spacing, which doesn't seem to impact the spacing preceding the link:

    var body: some View {
        Markdown(text)
            .lineSpacing(12) // <-- addition here
            .lineLimit(4)
            .truncationMode(.tail)
            .padding(16)
    }

Screenshot here:
Screen Shot 2022-07-27 at 12 30 42 PM

The last thing to mention is that this behavior doesn't seem to happen when using the built-in SwiftUI.Text markdown support, i.e. Text(.init(text)) in the example above.

@gonzalezreal
Copy link
Owner

Hi @maciesielka,

This is an interesting issue. MarkdownUI renders the markdown into an NSAttributedString and then uses a UITextView/NSTextView to display it in a SwiftUI view hierarchy. MarkdownUI uses the truncation mode, line limit, and line spacing from the SwiftUI environment in the following ways:

  • Truncation mode and line limit are just passed directly to the internal text view's NSTextContainer
  • Line spacing is used in NSParagraphStyle.lineSpacing during the NSAttributedString rendering.

The markdown example that you're providing has two paragraphs, and I suspect that the text container is applying truncation mode and line limit per paragraph, which can be the expected behaviour. If you squash the link together with the text in the same paragraph you should see what you expect.

SwiftUI Text markdown support is limited to inline markdown (emphasis, strong, links, etc.) and does not cover blocks (headings, paragraphs, lists, quotes, code blocks, thematic breaks).

Let me know if this clarifies the behaviour you're seeing.

Thanks!
Guille

@maciesielka
Copy link
Author

Ahh okay. Not ideal, but that makes sense at a high level. Maybe I'll use a workaround to remove the interior spacing in the text while I'm attempting truncation.

Appreciate the response!

@totoroyyb
Copy link

Hi,

I also tried to use the lineLimit to limit the number of lines the MarkdownUI displays. However, I've encountered the same issue as discussed above. After reading over the discussion above, I agree it's not necessarily a bug.

However, I argue this is a wrong behavior based on the lineLimit semantic in SwiftUI view. It probably should correctly limit the entire content instead of applying it to each paragraph, just like how lineLimit behaves on Text.

I wonder if there is any plan to correct the behavior.

@gonzalezreal
Copy link
Owner

Hi @totoroyyb,

As I mentioned in #188 (a related issue), it is very challenging to implement the truncation behavior that the Text view has. The reason is that a Markdown view is composed of multiple Text and Image views using different layouts.

Here is a list of workarounds:

  • Truncate the Markdown contents before setting up the view
  • Clip the view to a fixed height, as shown here.
  • Use Text in those use cases that require truncation.

I could implement a markdownWordLimit(_:) modifier that limits the Markdown contents to the specified number of words. Would that solve your use case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants