Как отображать заголовки Markdown в SwiftUI AttributedString?

Я пытался использовать новую AttributedString , выпущенную с iOS 15, для рендеринга Markdown, хранящегося в переменной. Однако мне не удалось найти способ отображать заголовки уценки, такие как:

      # Title 1
### Title 3
###### Title 6

Вот мой код:

      let description = """
        # Hello World

        Coin coin
        """
let attributed = (try? AttributedString(markdown: description)) ?? AttributedString(description)
return ScrollView {
    Text(attributed)
        .padding(.horizontal)
}

Но вот что отображается в превью:

Кто-нибудь успешно заставил их работать или это что-то невозможно сделать на данный момент?

1 ответ

Уценка анализируется правильно, проблема, похоже, в том, что ничего не делается с намерениями презентации для заголовков.

Вы можете просмотреть намерения презентации и вручную применить стиль к заголовкам.

Вам придется использоватьinterpretedSyntax: .fullчто будет означать, что пробел игнорируется, поэтому вы можете добавить новую строку после каждого блока.

      extension AttributedString {
    init(styledMarkdown markdownString: String) throws {
        var output = try AttributedString(
            markdown: markdownString,
            options: .init(
                allowsExtendedAttributes: true,
                interpretedSyntax: .full,
                failurePolicy: .returnPartiallyParsedIfPossible
            ),
            baseURL: nil
        )

        for (intentBlock, intentRange) in output.runs[AttributeScopes.FoundationAttributes.PresentationIntentAttribute.self].reversed() {
            guard let intentBlock = intentBlock else { continue }
            for intent in intentBlock.components {
                switch intent.kind {
                case .header(level: let level):
                    switch level {
                    case 1:
                        output[intentRange].font = .system(.title).bold()
                    case 2:
                        output[intentRange].font = .system(.title2).bold()
                    case 3:
                        output[intentRange].font = .system(.title3).bold()
                    default:
                        break
                    }
                default:
                    break
                }
            }
            
            if intentRange.lowerBound != output.startIndex {
                output.characters.insert(contentsOf: "\n", at: intentRange.lowerBound)
            }
        }

        self = output
    }
}

Насколько я могу видеть толькоbaselineOffset,backgroundColor,font,foregroundColor,kern,strikethroughStyle,tracking, иunderlineStyleподдерживаются в SwiftUI.

Это не идеальное решение, но оно может приблизить вас к тому, что вам нужно.

Другие вопросы по тегам