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

Possible without SwiftUI? #315

Open
Elamuruga opened this issue May 8, 2024 · 4 comments
Open

Possible without SwiftUI? #315

Elamuruga opened this issue May 8, 2024 · 4 comments

Comments

@Elamuruga
Copy link

Elamuruga commented May 8, 2024

In my project I am working on a storyboard and UIKIt is it possible to use the swift-markdown plugin for that? I want to achieve Github-flavoured markdown support. Could @gonzalezreal or anyone help me with this? Thanks in advance.

@paulgessinger
Copy link

How about UIHostingController?

@paulocoutinhox
Copy link

I want use it with UIKit in a table view too. Is possible?

@yccheok
Copy link

yccheok commented Nov 21, 2024

It is possible to integrate swift-markdown-ui into your UIKit app, but it requires a few tips and tricks to make it work. I spent an entire day figuring this out, and I hope you find these insights helpful. The following solution has been tested and works well with both programmatically created UIs and Storyboard-based UIs.

Here's the code snippet.


    import UIKit
    import SwiftUI
    import MarkdownUI

    struct MarkdownView: View {
        @State var markdownString: String

        var body: some View {

            VStack(alignment: .leading) {
                Markdown {
                    markdownString
                }
                .textSelection(.enabled)
                .markdownTheme(.gitHub)
                Spacer()
            }
        }
    }

    class ViewController: UIViewController {

        @IBOutlet weak var scrollView: UIScrollView!
        
        @IBOutlet weak var stackView: UIStackView!
        
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            addYellowButton()
            
            setupMarkdown()
            
            addYellowButton()
        }

        private func addYellowButton() {
            // Add a button with a yellow background to the stack view
            let yellowButton = UIButton(type: .system)
            yellowButton.backgroundColor = .yellow
            yellowButton.setTitle("Yellow Button", for: .normal)
            yellowButton.setTitleColor(.black, for: .normal)
            //yellowButton.heightAnchor.constraint(equalToConstant: 50).isActive = true // Set button height
            stackView.addArrangedSubview(yellowButton)
        }
        
        private func setupMarkdown() {
            // Define your markdown content
            let markdownContent =
    """
    # START OF MARKDOWN

    # Headers

    ```
    # h1 Heading 8-)
    ## h2 Heading
    ### h3 Heading
    #### h4 Heading
    ##### h5 Heading
    ###### h6 Heading

    Alternatively, for H1 and H2, an underline-ish style:

    Alt-H1
    ======

    Alt-H2
    ------
    ```

    # h1 Heading 8-)
    ## h2 Heading
    ### h3 Heading
    #### h4 Heading
    ##### h5 Heading
    ###### h6 Heading

    Alternatively, for H1 and H2, an underline-ish style:

    Alt-H1
    ======

    Alt-H2
    ------

    ------

    # Emphasis

    ```
    Emphasis, aka italics, with *asterisks* or _underscores_.

    Strong emphasis, aka bold, with **asterisks** or __underscores__.

    Combined emphasis with **asterisks and _underscores_**.

    Strikethrough uses two tildes. ~~Scratch this.~~

    **This is bold text**

    __This is bold text__

    *This is italic text*

    _This is italic text_

    ~~Strikethrough~~
    ```

    Emphasis, aka italics, with *asterisks* or _underscores_.

    # END OF MARKDOWN
    """

            print(markdownContent)
            
            // Create the SwiftUI view and pass the markdown content
            let markdownView = MarkdownView(markdownString: markdownContent)
                
            // Embed the SwiftUI view in a UIHostingController
            let hostingController = UIHostingController(rootView: markdownView)

            // https://medium.com/arcush-tech/two-pitfalls-to-avoid-when-working-with-uihostingcontroller-534d1507563e
            hostingController.sizingOptions = .intrinsicContentSize
            hostingController.safeAreaRegions = []
            
            // Add the hostingController as a child
            addChild(hostingController)

            stackView.addArrangedSubview(hostingController.view)
            
            hostingController.didMove(toParent: self)
        }
        
        private func setupScrollView() {
            /*
            // Create the scroll view
            let scrollView = UIScrollView()
            
            scrollView.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(scrollView)

            // Pin the scroll view to the edges of the view
            NSLayoutConstraint.activate([
                scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
                scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
                scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
            ])
            */
            
            /*
            // Create the vertical stack view
            stackView = UIStackView()
            stackView.axis = .vertical
            stackView.spacing = 0
            stackView.alignment = .fill
            stackView.distribution = .equalSpacing
            stackView.translatesAutoresizingMaskIntoConstraints = false
            scrollView.addSubview(stackView)
        
            // Pin the stack view to the scroll view's content layout
            NSLayoutConstraint.activate([
                stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
                stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
                stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
                stackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
                stackView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor) // Maintain stack view width equal to scroll view
            ])
            */
        }
    }

The biggest gotcha when using UIHostingController is that it might not resize properly when integrated into UIKit. Adding the following two lines of code will help it work correctly in most cases.


            hostingController.sizingOptions = .intrinsicContentSize
            hostingController.safeAreaRegions = []

@paulocoutinhox
Copy link

Thanks a lot.

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

4 participants