diff --git a/Sources/QuickLayout/QuickLayout/__showcase__/4-ListExample/BarsListViewController.swift b/Sources/QuickLayout/QuickLayout/__showcase__/4-ListExample/BarsListViewController.swift index 8c94f63..8e7c6d2 100644 --- a/Sources/QuickLayout/QuickLayout/__showcase__/4-ListExample/BarsListViewController.swift +++ b/Sources/QuickLayout/QuickLayout/__showcase__/4-ListExample/BarsListViewController.swift @@ -10,13 +10,15 @@ import UIKit final class BarsListViewController: UIViewController { private var dataSource: UICollectionViewDiffableDataSource? - private lazy var collectionView = { + private lazy var layout = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .vertical layout.minimumLineSpacing = 0 layout.minimumLineSpacing = 0 - // patternlint-disable-next-line ig-avoid-uiscreen-bounds-swift - layout.itemSize = UIScreen.main.bounds.size + return layout + }() + + private lazy var collectionView = { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) collectionView.register(BarCardViewCell.self, forCellWithReuseIdentifier: BarCardViewCell.reuseIdentifier) @@ -37,6 +39,13 @@ final class BarsListViewController: UIViewController { self.view = collectionView } + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + if layout.itemSize != view.bounds.size { + layout.itemSize = view.bounds.size + } + } + func configureDataSource() { dataSource = UICollectionViewDiffableDataSource(collectionView: collectionView) { (collectionView: UICollectionView, indexPath: IndexPath, item: BarModel) -> UICollectionViewCell? in guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BarCardViewCell.reuseIdentifier, for: indexPath) as? BarCardViewCell else { diff --git a/Sources/QuickLayout/QuickLayout/__showcase__/QuickLayoutShowcaseApp.swift b/Sources/QuickLayout/QuickLayout/__showcase__/QuickLayoutShowcaseApp.swift index ba4d014..d9481a5 100644 --- a/Sources/QuickLayout/QuickLayout/__showcase__/QuickLayoutShowcaseApp.swift +++ b/Sources/QuickLayout/QuickLayout/__showcase__/QuickLayoutShowcaseApp.swift @@ -37,7 +37,16 @@ struct ShowcaseApp: View { [ StateManagementView.self ]), - + SCSection( + "Animations", + [ + UpdatingWithAnimationView.self + ]), + SCSection( + "List", + [ + BarsListViewController.self + ]), SCSection( "Alignment", [ @@ -101,34 +110,82 @@ struct ShowcaseApp: View { private struct ShowcaseViewRepresentable: UIViewRepresentable { - let view: UIView.Type + let viewType: UIView.Type init(_ viewType: UIView.Type) { - self.view = viewType + self.viewType = viewType } func makeUIView(context: Context) -> some UIView { - view.init() as UIView + viewType.init() as UIView } func updateUIView(_ uiView: UIViewType, context: Context) { } } +private struct ShowcaseViewControllerRepresentable: UIViewControllerRepresentable { + + let viewControllerType: UIViewController.Type + + init(_ viewControllerType: UIViewController.Type) { + self.viewControllerType = viewControllerType + } + + func makeUIViewController(context: Context) -> some UIViewController { + viewControllerType.init() as UIViewController + } + + func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { + } +} + +private enum ShowcaseType { + case view(UIView.Type) + case viewController(UIViewController.Type) + + var underlyingType: Any.Type { + switch self { + case let .view(viewType): + return viewType + case let .viewController(viewControllerType): + return viewControllerType + } + } +} + +private protocol ShowcaseTypeConvertable { + static var showcaseType: ShowcaseType { get } +} + +extension UIView: ShowcaseTypeConvertable { + fileprivate static var showcaseType: ShowcaseType { .view(Self.self) } +} + +extension UIViewController: ShowcaseTypeConvertable { + fileprivate static var showcaseType: ShowcaseType { .viewController(Self.self) } +} + private struct SCShowcase: Identifiable, Hashable { let id = UUID() - let viewType: UIView.Type + let showcaseType: ShowcaseType let label: String - init(viewType: UIView.Type) { - self.viewType = viewType - self.label = String(describing: viewType).splittingCamelCase() + init(showcaseType: ShowcaseType) { + self.showcaseType = showcaseType + self.label = String(describing: showcaseType.underlyingType).splittingCamelCase() } @MainActor + @ViewBuilder func view() -> some View { - ShowcaseViewRepresentable(viewType) + switch showcaseType { + case let .view(viewType): + ShowcaseViewRepresentable(viewType) + case let .viewController(viewControllerType): + ShowcaseViewControllerRepresentable(viewControllerType) + } } static func == (lhs: SCShowcase, rhs: SCShowcase) -> Bool { @@ -142,7 +199,13 @@ private struct SCShowcase: Identifiable, Hashable { private extension String { func splittingCamelCase() -> String { - let stripped = self.hasSuffix("View") ? String(self.dropLast(4)) : self + let stripped = self.hasSuffix("View") + ? String(self.dropLast(4)) + : ( + self.hasSuffix("ViewController") + ? String(self.dropLast(14)) + : self + ) // Split by uppercase letters let words = stripped.reduce("") { result, char in @@ -164,9 +227,9 @@ private struct SCSection: Identifiable, Hashable { let showscases: [SCShowcase] let title: String - init(_ title: String, _ showcases: [UIView.Type]) { + init(_ title: String, _ showcases: [ShowcaseTypeConvertable.Type]) { self.title = title - self.showscases = showcases.map { SCShowcase(viewType: $0) } + self.showscases = showcases.map { SCShowcase(showcaseType: $0.showcaseType) } } }