gonzalezreal / swift-markdown-ui

Display and customize Markdown text in SwiftUI
MIT License
2.25k stars 267 forks source link

Markdown out of bounds instead of truncating #188

Closed kevinvanmierlo closed 1 year ago

kevinvanmierlo commented 1 year ago

When using the Markdown view with a set height it still goes out of bounds instead of truncating. For example:

Markdown(item.markdownText)
    .frame(height: 100, alignment: .topLeading)
    .background(Color.red)

If the markdownText is more text than what fits inside the 100 height it will go out of bounds. Normal SwiftUI Text will truncate when that happens.

Checklist

Steps to reproduce Just paste the above code sample in a new project. It doesn't even have to be specific Markdown. It can just be regular text and will still go out of bounds.

Expected behavior I would expect it to truncate like the Text of SwiftUI would do. You can replace Markdown with Text to see that that is working.

Screenshots Screenshot 2023-02-13 at 12 38 06

Version information

gonzalezreal commented 1 year ago

Hi @kevinvanmierlo,

It is challenging, if not impossible, to implement the same text truncation that the Text view has, as a Markdown view results from composing multiple Text and Image views using different layouts.

The workaround is to use either the clipped(antialiased:) or the clipShape(_:style:) modifiers to clip the contents.

kevinvanmierlo commented 1 year ago

Hi @gonzalezreal,

Thanks for the quick response! That's unfortunate to hear. I have a dynamic text and title with optional image in a horizontal list (so same size). It should be truncated when there is no more room. Perhaps I'll remove the Markdown there and only support it on the detail page for now. Besides that, the library works amazing!

gonzalezreal commented 1 year ago

You can also try a different visual cue to indicate that the text is truncated, for instance:

struct ContentView: View {
  var body: some View {
    Markdown {
      """
      You can quote text with a `>`.

      > Outside of a dog, a book is
      > man's best friend. Inside of
      > a dog it's too dark to read.

      – Groucho Marx
      """
    }
    .frame(height: 80, alignment: .top)
    .clipped()
    .mask {
      LinearGradient(
        colors: [.black, .clear],
        startPoint: .center, endPoint: .bottom
      )
    }
    .overlay(alignment: .bottomTrailing) {
      Image(systemName: "ellipsis.rectangle.fill")
        .imageScale(.large)
        .foregroundColor(.secondary)
    }
    .padding()
    .background(Color(.secondarySystemBackground))
  }
}
Screenshot 2023-02-15 at 09 31 19
kevinvanmierlo commented 1 year ago

Thanks for the suggestions! The second and the third option could be used, but it's not really what I was looking for. But I'll take a look at it what's the best option for my use case.

gonzalezreal commented 1 year ago

I have updated my previous comment with a code snippet and a screenshot to give you an idea of how it could look. Obviously, I am not a designer 😅.

With that information in place, I will close this issue. Feel free to open a new discussion if you have any more ideas about this.

kevinvanmierlo commented 1 year ago

Thanks for that! It looks great, but it does look like you can expand it there, and that is not the case for me. It is a list with a part of the text and you can click on it to see all the text. But a wish was to get some markup there. That's why the ellipsis in the text would work best for our use case. But thanks again! I can probably use this trick elsewhere