Mycroft Canner
Mycroft Canner

Reputation: 1997

How to wrap a SwiftUI View inside a ASDisplayNode

Today I was trying to figure out a way to interface SwiftUI and Texture (AsyncDisplayKit).

That way I get the speed and benefits of AsyncDisplayKit, ASNetworkImage, etc. and the flexibility of SwiftUI and Combine in my detail views.

Upvotes: 0

Views: 1778

Answers (1)

Mycroft Canner
Mycroft Canner

Reputation: 1997

Interfacing SwiftUI and Texture / AsyncDisplayKit

We can initialize a node and provide a SwiftUI view to be used as the backing view. The Text view nests in a UIHostingController, a UIViewController subclass that represents a SwiftUI view within UIKit contexts.

The view is provided via a block that will return a view so that the actual construction of the view can be saved until later. The node display step happens synchronously because a node can only be asynchronously displayed when it wraps an _ASDisplayView (the internal view subclass), not when it wraps a UIView.

//
//  HostingNode.swift
//

import AsyncDisplayKit
import SwiftUI

class HostingNode: ASDisplayNode {

    var viewController: UIViewController?

    override init() {
        super.init()

        setViewBlock { [weak self]() -> UIView in
            self?.viewController = self?.makeHostingController()
            return self?.viewController?.view ?? UIView()
        }
    }

    private func makeHostingController() -> UIViewController {
        UIHostingController(
            rootView: Text("Attention")
        )
    }
}

References:

Upvotes: 1

Related Questions