Skip to content

Instantly share code, notes, and snippets.

@YanSte
Last active August 18, 2022 08:01
Show Gist options
  • Save YanSte/36222fc2db3a164600eb07020dae8004 to your computer and use it in GitHub Desktop.
Save YanSte/36222fc2db3a164600eb07020dae8004 to your computer and use it in GitHub Desktop.
SwiftUICollectionViewCell, SwiftUIView embed in UICollectioViewCell
import SwiftUI
import UIKit
/// Subclass for embedding a SwiftUI View inside of UICollectionViewCell
open class SwiftUICollectionViewCell: UICollectionViewCell {
static var reuseIdentifier: String {
"\(self)"
}
/// Controller to host the SwiftUI View
private(set) var host: UIHostingController<AnyView>?
private(set) var onPrepareForReuse: (() ->())? = nil
// MARK: Initializers
deinit {
host?.willMove(toParent: nil)
host?.view.removeFromSuperview()
host?.removeFromParent()
host = nil
}
// MARK: Public methods
/// Add host controller to the heirarchy
/// - Parameters:
/// - parent: Parent UIViewController
/// - content: View Content
/// - viewModel: ViewModel of `ReusableSwiftUICollectionViewModelCell` for `prepareForReuse`,
///
/// **Note:**
/// - **In the case creation instance**: The `appear` method of `SwitfUI` is called once at the creation instance.
///
/// - **In the case of reuse**: The `appear` method is not called because `UIHostingController` already appeared (Reusable cell).
/// The method `onPrepareForReuse` will give you the indication of a reuse of the cell.
/// (like `PrepareForReuse` of `collectionViewCell`)
///
public func configure(
parent: UIViewController,
view content: AnyView,
inset: EdgeInsets = .zero,
onPrepareForReuse: (() ->())? = nil
) {
self.onPrepareForReuse = onPrepareForReuse
let contentConfigured = content.padding(inset).eraseToAnyView()
if let host = host {
host.rootView = contentConfigured
host.view.layoutIfNeeded()
} else {
let host = UIHostingController(rootView: contentConfigured)
parent.addChild(host)
host.didMove(toParent: parent)
contentView.addSubview(host.view)
host.view.frame = contentView.bounds
host.view.backgroundColor = .clear
host.view.bindFrameToSuperviewBounds()
self.host = host
}
}
open override func prepareForReuse() {
super.prepareForReuse()
self.onPrepareForReuse?()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment