Last active
August 18, 2022 08:01
-
-
Save YanSte/36222fc2db3a164600eb07020dae8004 to your computer and use it in GitHub Desktop.
SwiftUICollectionViewCell, SwiftUIView embed in UICollectioViewCell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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