How to show HTML or Markdown in a SwiftUI Text?

后端 未结 5 1494
孤城傲影
孤城傲影 2020-12-31 12:39

How can I set a SwiftUI Text to display rendered HTML or Markdown?

Something like this:

Text(HtmlRenderedString(fromString: \"

        
相关标签:
5条回答
  • 2020-12-31 13:02

    You can try to use the package https://github.com/iwasrobbed/Down, generate HTML or MD from you markdown string, then create a custom UILabel subclass and make it available to SwiftUI like in the following example:

    struct TextWithAttributedString: UIViewRepresentable {
    
        var attributedString: NSAttributedString
    
        func makeUIView(context: Context) -> ViewWithLabel {
            let view = ViewWithLabel(frame: .zero)
            return view
        }
    
        func updateUIView(_ uiView: ViewWithLabel, context: Context) {
            uiView.setString(attributedString)
        }
    }
    
    class ViewWithLabel : UIView {
        private var label = UILabel()
    
        override init(frame: CGRect) {
            super.init(frame:frame)
            self.addSubview(label)
            label.numberOfLines = 0
            label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        func setString(_ attributedString:NSAttributedString) {
            self.label.attributedText = attributedString
        }
    
        override var intrinsicContentSize: CGSize {
            label.sizeThatFits(CGSize(width: UIScreen.main.bounds.width - 50, height: 9999))
        }
    }
    

    I have kind of success with that but cannot get the frame of the label subclass right. Maybe I need to use GeometryReader for that.

    0 讨论(0)
  • 2020-12-31 13:03

    If you don't need to specifically use a Text view. You can create a UIViewRepresentable that shows a WKWebView and simple call loadHTMLString().

    import WebKit
    import SwiftUI
    
    struct HTMLStringView: UIViewRepresentable {
        let htmlContent: String
    
        func makeUIView(context: Context) -> WKWebView {
            return WKWebView()
        }
    
        func updateUIView(_ uiView: WKWebView, context: Context) {
            uiView.loadHTMLString(htmlContent, baseURL: nil)
        }
    }
    

    In your body simple call this object like this:

    import SwiftUI
    
    struct Test: View {
        var body: some View {
            VStack {
                Text("Testing HTML Content")
                Spacer()
                HTMLStringView(htmlContent: "<h1>This is HTML String</h1>")
                Spacer()
            }
        }
    }
    
    struct Test_Previews: PreviewProvider {
        static var previews: some View {
            Test()
        }
    }
    
    0 讨论(0)
  • 2020-12-31 13:21

    Text can just display Strings. You can use a UIViewRepresentable with an UILabel and attributedText.

    Probably attributedText text support will come later for SwiftUI.Text.

    0 讨论(0)
  • 2020-12-31 13:25

    Since I have found another solution I will like to share it with you.

    Create a new View Representable

    struct HTMLText: UIViewRepresentable {
    
       let html: String
    
       func makeUIView(context: UIViewRepresentableContext<Self>) -> UILabel {
            let label = UILabel()
            DispatchQueue.main.async {
                let data = Data(self.html.utf8)
                if let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {
                    label.attributedText = attributedString
                }
            }
    
            return label
        }
    
        func updateUIView(_ uiView: UILabel, context: Context) {}
    }
    

    And use it later like this:

    HTMLText(html: "<h1>Your html string</h1>")
    
    0 讨论(0)
  • 2020-12-31 13:29

    I created a markdown library specifically for SwiftUI:

    https://github.com/Lambdo-Labs/MDText

    Feel free to contribute!

    0 讨论(0)
提交回复
热议问题