Skip to content

Instantly share code, notes, and snippets.

@kylebrowning
Last active April 1, 2024 18:38
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kylebrowning/044b837a9a98135a15ccbb34f664e31f to your computer and use it in GitHub Desktop.
Save kylebrowning/044b837a9a98135a15ccbb34f664e31f to your computer and use it in GitHub Desktop.
//
// HostingCell.swift
// theathletic-ios
//
// Created by .
// Copyright © 2021 The Athletic. All rights reserved.
//
import SwiftUI
import UIKit
class HostingCell<Content: View>: UICollectionViewCell {
private let hostingController = UIHostingController<Content?>(rootView: nil)
deinit {
removeHostingControllerFromParent()
}
private func removeHostingControllerFromParent() {
hostingController.willMove(toParent: nil)
hostingController.view.removeFromSuperview()
hostingController.removeFromParent()
}
func configure(with view: Content, in parent: UIViewController?) {
guard let parent = parent else {
let message = "parent viewController is required"
assertionFailure(message)
ATHLogger(category: .application).warning(message)
return
}
hostingController.rootView = view
hostingController.view.invalidateIntrinsicContentSize()
let requiresControllerMove = hostingController.parent != parent
if requiresControllerMove {
removeHostingControllerFromParent()
parent.addChild(hostingController)
}
if !contentView.subviews.contains(hostingController.view) {
setUpUI()
}
if requiresControllerMove {
hostingController.didMove(toParent: parent)
}
}
private func setUpUI() {
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(hostingController.view)
hostingController.view.backgroundColor = .clear
NSLayoutConstraint.activate([
hostingController.view.topAnchor.constraint(
equalTo: contentView.topAnchor
),
hostingController.view.bottomAnchor.constraint(
equalTo: contentView.bottomAnchor
),
hostingController.view.leadingAnchor.constraint(
equalTo: contentView.leadingAnchor
),
hostingController.view.trailingAnchor.constraint(
equalTo: contentView.trailingAnchor
),
])
}
}
collection.register(HostingCell<MySwiftUICell>.self)
struct MySwiftUICell: View {
var body: some View.....
}
....
let cell =
collection.dequeueReusableCell(for: indexPath)
as HostingCell<MySwiftUICell>
cell.configure(
with: MySwiftUICell(
viewModel: myViewModel
),
in: parent
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment