mirror of
https://github.com/facebookincubator/QuickLayout
synced 2026-04-21 13:37:22 +00:00
Add Animations and List showcase (#13)
Summary: Pull Request resolved: https://github.com/facebookincubator/QuickLayout/pull/13 Reviewed By: saadhzahid Differential Revision: D90382201 Pulled By: constantine-fry fbshipit-source-id: 6726c6b6ee9c473b3a2a43880c9acf65e4f40ae9
This commit is contained in:
parent
54c78ef52b
commit
bb0f8bbcbf
2 changed files with 88 additions and 15 deletions
|
|
@ -10,13 +10,15 @@ import UIKit
|
|||
final class BarsListViewController: UIViewController {
|
||||
private var dataSource: UICollectionViewDiffableDataSource<Int, BarModel>?
|
||||
|
||||
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<Int, BarModel>(collectionView: collectionView) { (collectionView: UICollectionView, indexPath: IndexPath, item: BarModel) -> UICollectionViewCell? in
|
||||
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BarCardViewCell.reuseIdentifier, for: indexPath) as? BarCardViewCell else {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,16 @@ struct ShowcaseApp: View {
|
|||
[
|
||||
StateManagementView.self
|
||||
]),
|
||||
|
||||
SCSection(
|
||||
"Animations",
|
||||
[
|
||||
UpdatingWithAnimationView.self
|
||||
]),
|
||||
SCSection(
|
||||
"List",
|
||||
[
|
||||
BarsListViewController.self
|
||||
]),
|
||||
SCSection(
|
||||
"Alignment",
|
||||
[
|
||||
|
|
@ -101,34 +110,83 @@ 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
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 +200,12 @@ 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
|
||||
|
|
@ -159,14 +222,15 @@ private extension String {
|
|||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private struct SCSection: Identifiable, Hashable {
|
||||
let id = UUID()
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue