Created
June 22, 2020 07:37
-
-
Save IsaacXen/4cd5e75abbe1386a3d2e4d264437f1d1 to your computer and use it in GitHub Desktop.
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 UIKit | |
public extension NSCollectionLayoutAnchor { | |
struct Offset { | |
fileprivate var absolute: CGPoint? | |
fileprivate var fractional: CGPoint? | |
private init(absolute: CGPoint?, fractional: CGPoint?) { | |
self.absolute = absolute | |
self.fractional = fractional | |
} | |
public static func absolute(x: CGFloat) -> Offset { | |
absolute(x: x, y: 0) | |
} | |
public static func absolute(y: CGFloat) -> Offset { | |
absolute(x: 0, y: y) | |
} | |
public static func absolute(x: CGFloat, y: CGFloat) -> Offset { | |
Offset(absolute: CGPoint(x: x, y: y), fractional: nil) | |
} | |
public static func fractional(x: CGFloat) -> Offset { | |
fractional(x: x, y: 0) | |
} | |
public static func fractional(y: CGFloat) -> Offset { | |
fractional(x: 0, y: y) | |
} | |
public static func fractional(x: CGFloat, y: CGFloat) -> Offset { | |
Offset(absolute: nil, fractional: CGPoint(x: x, y: y)) | |
} | |
} | |
} | |
// MARK: - Supplementary Item | |
public class LayoutSupplementaryItem { | |
fileprivate var width: NSCollectionLayoutDimension | |
fileprivate var height: NSCollectionLayoutDimension | |
fileprivate var elementKind: String | |
fileprivate var containerAnchor: NSCollectionLayoutAnchor = NSCollectionLayoutAnchor(edges: []) | |
fileprivate var itemAnchor: NSCollectionLayoutAnchor = NSCollectionLayoutAnchor(edges: []) | |
fileprivate var zIndex: Int? = nil | |
public init( | |
_ elementKind: String, | |
width: NSCollectionLayoutDimension = .fractionalWidth(0.2), | |
height: NSCollectionLayoutDimension = .fractionalHeight(0.2) | |
) { | |
self.width = width | |
self.height = height | |
self.elementKind = elementKind | |
} | |
public func containerAnchor(_ edges: NSDirectionalRectEdge, offset: NSCollectionLayoutAnchor.Offset = .absolute(x: 0, y: 0)) -> LayoutSupplementaryItem { | |
self.containerAnchor = makeAnchor(edges: edges, offset: offset) | |
return self | |
} | |
public func itemAnchor(_ edges: NSDirectionalRectEdge, offset: NSCollectionLayoutAnchor.Offset = .absolute(x: 0, y: 0)) -> LayoutSupplementaryItem { | |
self.itemAnchor = makeAnchor(edges: edges, offset: offset) | |
return self | |
} | |
private func makeAnchor(edges: NSDirectionalRectEdge, offset: NSCollectionLayoutAnchor.Offset = .absolute(x: 0, y: 0)) -> NSCollectionLayoutAnchor { | |
if let fractionalOffset = offset.fractional { | |
return NSCollectionLayoutAnchor(edges: edges, fractionalOffset: fractionalOffset) | |
} else if let absoluteOffset = offset.absolute { | |
return NSCollectionLayoutAnchor(edges: edges, absoluteOffset: absoluteOffset) | |
} else { | |
return NSCollectionLayoutAnchor(edges: edges, absoluteOffset: CGPoint(x: 0, y: 0)) | |
} | |
} | |
public func zIndex(_ zIndex: Int) -> LayoutSupplementaryItem { | |
self.zIndex = zIndex | |
return self | |
} | |
} | |
fileprivate extension NSCollectionLayoutSupplementaryItem { | |
convenience init(_ config: LayoutSupplementaryItem) { | |
self.init(layoutSize: NSMakeSize(config.width, config.height), elementKind: config.elementKind, containerAnchor: config.containerAnchor, itemAnchor: config.itemAnchor) | |
if let zIndex = config.zIndex { | |
self.zIndex = zIndex | |
} | |
} | |
} | |
@_functionBuilder | |
public struct LayoutSupplementaryItemBuilder { | |
public static func buildBlock(_ items: LayoutSupplementaryItem...) -> [LayoutSupplementaryItem] { | |
items | |
} | |
} | |
// MARK: - Boundary Supplementary Item | |
public class LayoutBoundarySupplementaryItem { | |
fileprivate var width: NSCollectionLayoutDimension | |
fileprivate var height: NSCollectionLayoutDimension | |
fileprivate var elementKind: String | |
fileprivate var alignment: NSRectAlignment = .none | |
fileprivate var offset: CGPoint = .zero | |
fileprivate var pinToVisibleBounds: Bool = false | |
fileprivate var extendsBoundary: Bool = false | |
public init( | |
_ elementKind: String, | |
width: NSCollectionLayoutDimension = .fractionalWidth(0.2), | |
height: NSCollectionLayoutDimension = .fractionalHeight(0.2) | |
) { | |
self.elementKind = elementKind | |
self.width = width | |
self.height = height | |
} | |
public func alignment(_ alignment: NSRectAlignment) -> LayoutBoundarySupplementaryItem { | |
self.alignment = alignment | |
return self | |
} | |
public func extendsBoundary(_ flag: Bool) -> LayoutBoundarySupplementaryItem { | |
self.extendsBoundary = flag | |
return self | |
} | |
public func absoluteOffset(x: CGFloat = 0, y: CGFloat = 0) -> LayoutBoundarySupplementaryItem { | |
self.offset = CGPoint(x: x, y: y) | |
return self | |
} | |
public func pinToVisibleBounds(_ flag: Bool) -> LayoutBoundarySupplementaryItem { | |
self.pinToVisibleBounds = flag | |
return self | |
} | |
} | |
fileprivate extension NSCollectionLayoutBoundarySupplementaryItem { | |
convenience init(_ config: LayoutBoundarySupplementaryItem) { | |
self.init(layoutSize: NSMakeSize(config.width, config.height), elementKind: config.elementKind, alignment: config.alignment, absoluteOffset: config.offset) | |
self.extendsBoundary = config.extendsBoundary | |
self.pinToVisibleBounds = config.pinToVisibleBounds | |
} | |
} | |
@_functionBuilder | |
public struct LayoutBoundarySupplementaryItemBuilder { | |
public static func buildBlock(_ items: LayoutBoundarySupplementaryItem...) -> [LayoutBoundarySupplementaryItem] { | |
items | |
} | |
} | |
// MARK: - Decoration Item | |
public class LayoutDecorationItem { | |
fileprivate enum Kind { | |
case background | |
} | |
fileprivate var elementKind: String | |
fileprivate var kind: Kind | |
fileprivate var zIndex: Int? = nil | |
private init(kind: Kind, elementKind: String) { | |
self.kind = kind | |
self.elementKind = elementKind | |
} | |
func zIndex(_ zIndex: Int) -> LayoutDecorationItem { | |
self.zIndex = zIndex | |
return self | |
} | |
} | |
fileprivate extension NSCollectionLayoutDecorationItem { | |
static func convert(from config: LayoutDecorationItem) -> NSCollectionLayoutDecorationItem { | |
var item: NSCollectionLayoutDecorationItem | |
switch config.kind { | |
case .background: | |
item = NSCollectionLayoutDecorationItem.background(elementKind: config.elementKind) | |
} | |
if let zIndex = config.zIndex { | |
item.zIndex = zIndex | |
} | |
return item | |
} | |
} | |
@_functionBuilder | |
struct LayoutDecorationItemBuilder { | |
public static func buildBlock(_ items: LayoutDecorationItem...) -> [LayoutDecorationItem] { | |
items | |
} | |
} | |
// MARK: - Item | |
public class LayoutItem { | |
fileprivate var width: NSCollectionLayoutDimension | |
fileprivate var height: NSCollectionLayoutDimension | |
fileprivate var contentInsets: NSDirectionalEdgeInsets = .zero | |
fileprivate var edgeSpacing: NSCollectionLayoutEdgeSpacing? = nil | |
fileprivate var supplementaryItems: [NSCollectionLayoutSupplementaryItem] | |
public init( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1) | |
) { | |
self.width = width | |
self.height = height | |
self.supplementaryItems = [] | |
} | |
public init( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> [LayoutSupplementaryItem] | |
) { | |
self.width = width | |
self.height = height | |
self.supplementaryItems = supplementaryItemsBuilder().map { NSCollectionLayoutSupplementaryItem($0) } | |
} | |
public init( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
@LayoutSupplementaryItemBuilder supplementaryItem: () -> LayoutSupplementaryItem | |
) { | |
self.width = width | |
self.height = height | |
self.supplementaryItems = [NSCollectionLayoutSupplementaryItem(supplementaryItem())] | |
} | |
public func contentInsets(top: CGFloat = 0, leading: CGFloat = 0, bottom: CGFloat = 0, trailing: CGFloat = 0) -> LayoutItem { | |
self.contentInsets = NSDirectionalEdgeInsets(top: top, leading: leading, bottom: bottom, trailing: trailing) | |
return self | |
} | |
public func edgeSpacing(top: NSCollectionLayoutSpacing? = nil, leading: NSCollectionLayoutSpacing? = nil, bottom: NSCollectionLayoutSpacing? = nil, trailing: NSCollectionLayoutSpacing? = nil) -> LayoutItem { | |
self.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: leading, top: top, trailing: trailing, bottom: bottom) | |
return self | |
} | |
} | |
fileprivate extension NSCollectionLayoutItem { | |
convenience init(_ config: LayoutItem) { | |
self.init(layoutSize: NSMakeSize(config.width, config.height), supplementaryItems: config.supplementaryItems) | |
self.contentInsets = config.contentInsets | |
self.edgeSpacing = config.edgeSpacing | |
} | |
} | |
@_functionBuilder | |
public struct LayoutItemBuilder { | |
public static func buildBlock(_ items: LayoutItem...) -> [LayoutItem] { | |
items | |
} | |
} | |
// MARK: - Group | |
public class LayoutGroup { | |
fileprivate enum Kind { | |
case vertical, horizontal, custom | |
} | |
fileprivate var kind: Kind | |
fileprivate var width: NSCollectionLayoutDimension | |
fileprivate var height: NSCollectionLayoutDimension | |
fileprivate var subitems: [NSCollectionLayoutItem]? = nil | |
fileprivate var count: Int? = nil | |
fileprivate var interItemSpacing: NSCollectionLayoutSpacing? = nil | |
fileprivate var supplementaryItems: [NSCollectionLayoutSupplementaryItem] = [] | |
fileprivate var itemProvider: NSCollectionLayoutGroupCustomItemProvider? = nil | |
// horizontal | |
public static func horizontal( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
@LayoutItemBuilder itemsBuilder: () -> [LayoutItem] | |
) -> LayoutGroup { | |
horizontal(width: width, height: height, supplementaryItemsBuilder: { [] }, itemsBuilder: itemsBuilder) | |
} | |
public static func horizontal( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
count: Int? = nil, | |
@LayoutItemBuilder itemsBuilder: () -> LayoutItem | |
) -> LayoutGroup { | |
horizontal(width: width, height: height, count: count, supplementaryItemsBuilder: { [] }, itemsBuilder: itemsBuilder) | |
} | |
public static func horizontal( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> LayoutSupplementaryItem, | |
@LayoutItemBuilder itemsBuilder: () -> [LayoutItem] | |
) -> LayoutGroup { | |
horizontal(width: width, height: height, supplementaryItemsBuilder: { [supplementaryItemsBuilder()] }, itemsBuilder: itemsBuilder) | |
} | |
public static func horizontal( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
count: Int? = nil, | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> LayoutSupplementaryItem, | |
@LayoutItemBuilder itemsBuilder: () -> LayoutItem | |
) -> LayoutGroup { | |
horizontal(width: width, height: height, count: count, supplementaryItemsBuilder: { [supplementaryItemsBuilder()] }, itemsBuilder: itemsBuilder) | |
} | |
public static func horizontal( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> [LayoutSupplementaryItem], | |
@LayoutItemBuilder itemsBuilder: () -> [LayoutItem] | |
) -> LayoutGroup { | |
let group = LayoutGroup(.horizontal, width: width, height: height) | |
group.subitems = itemsBuilder().map { NSCollectionLayoutItem($0) } | |
group.supplementaryItems = supplementaryItemsBuilder().map { NSCollectionLayoutSupplementaryItem($0) } | |
return group | |
} | |
public static func horizontal( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
count: Int? = nil, | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> [LayoutSupplementaryItem], | |
@LayoutItemBuilder itemsBuilder: () -> LayoutItem | |
) -> LayoutGroup { | |
let group = LayoutGroup(.horizontal, width: width, height: height) | |
group.count = count | |
group.subitems = [NSCollectionLayoutItem(itemsBuilder())] | |
group.supplementaryItems = supplementaryItemsBuilder().map { NSCollectionLayoutSupplementaryItem($0) } | |
return group | |
} | |
// vertical | |
public static func vertical( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
@LayoutItemBuilder itemsBuilder: () -> [LayoutItem] | |
) -> LayoutGroup { | |
vertical(width: width, height: height, supplementaryItemsBuilder: { [] }, itemsBuilder: itemsBuilder) | |
} | |
public static func vertical( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
count: Int? = nil, | |
@LayoutItemBuilder itemsBuilder: () -> LayoutItem | |
) -> LayoutGroup { | |
vertical(width: width, height: height, count: count, supplementaryItemsBuilder: { [] }, itemsBuilder: itemsBuilder) | |
} | |
public static func vertical( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> LayoutSupplementaryItem, | |
@LayoutItemBuilder itemsBuilder: () -> [LayoutItem] | |
) -> LayoutGroup { | |
vertical(width: width, height: height, supplementaryItemsBuilder: { [supplementaryItemsBuilder()] }, itemsBuilder: itemsBuilder) | |
} | |
public static func vertical( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
count: Int? = nil, | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> LayoutSupplementaryItem, | |
@LayoutItemBuilder itemsBuilder: () -> LayoutItem | |
) -> LayoutGroup { | |
vertical(width: width, height: height, count: count, supplementaryItemsBuilder: { [supplementaryItemsBuilder()] }, itemsBuilder: itemsBuilder) | |
} | |
public static func vertical( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> [LayoutSupplementaryItem], | |
@LayoutItemBuilder itemsBuilder: () -> [LayoutItem] | |
) -> LayoutGroup { | |
let group = LayoutGroup(.vertical, width: width, height: height) | |
group.subitems = itemsBuilder().map { NSCollectionLayoutItem($0) } | |
group.supplementaryItems = supplementaryItemsBuilder().map { NSCollectionLayoutSupplementaryItem($0) } | |
return group | |
} | |
public static func vertical( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
count: Int? = nil, | |
@LayoutSupplementaryItemBuilder supplementaryItemsBuilder: () -> [LayoutSupplementaryItem], | |
@LayoutItemBuilder itemsBuilder: () -> LayoutItem | |
) -> LayoutGroup { | |
let group = LayoutGroup(.vertical, width: width, height: height) | |
group.count = count | |
group.subitems = [NSCollectionLayoutItem(itemsBuilder())] | |
group.supplementaryItems = supplementaryItemsBuilder().map { NSCollectionLayoutSupplementaryItem($0) } | |
return group | |
} | |
// custom | |
public static func custom( | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1), | |
itemPrivider: @escaping NSCollectionLayoutGroupCustomItemProvider | |
) -> LayoutGroup { | |
let group = LayoutGroup(.custom, width: width, height: height) | |
group.itemProvider = itemPrivider | |
return group | |
} | |
private init( | |
_ kind: Kind, | |
width: NSCollectionLayoutDimension = .fractionalWidth(1), | |
height: NSCollectionLayoutDimension = .fractionalHeight(1) | |
) { | |
self.kind = kind | |
self.width = width | |
self.height = height | |
} | |
public func interItemSpacing(_ spacing: NSCollectionLayoutSpacing) -> LayoutGroup { | |
self.interItemSpacing = spacing | |
return self | |
} | |
} | |
fileprivate extension NSCollectionLayoutGroup { | |
static func convert(from config: LayoutGroup) -> NSCollectionLayoutGroup { | |
var group: NSCollectionLayoutGroup | |
switch config.kind { | |
case .horizontal: | |
if let count = config.count { | |
group = NSCollectionLayoutGroup.horizontal(layoutSize: NSMakeSize(config.width, config.height), subitem: config.subitems?.first ?? NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .absolute(0), heightDimension: .absolute(0))), count: count) | |
} else { | |
group = NSCollectionLayoutGroup.horizontal(layoutSize: NSMakeSize(config.width, config.height), subitems: config.subitems ?? []) | |
} | |
case .vertical: | |
if let count = config.count { | |
group = NSCollectionLayoutGroup.vertical(layoutSize: NSMakeSize(config.width, config.height), subitem: config.subitems?.first ?? NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .absolute(0), heightDimension: .absolute(0))), count: count) | |
} else { | |
group = NSCollectionLayoutGroup.vertical(layoutSize: NSMakeSize(config.width, config.height), subitems: config.subitems ?? []) | |
} | |
case .custom: | |
group = NSCollectionLayoutGroup.custom(layoutSize: NSMakeSize(config.width, config.height), itemProvider: config.itemProvider ?? { _ in [] }) | |
} | |
group.interItemSpacing = config.interItemSpacing | |
group.supplementaryItems = config.supplementaryItems | |
return group | |
} | |
} | |
@_functionBuilder | |
public struct LayoutGroupBuilder { | |
public static func buildBlock(_ items: LayoutGroup...) -> [LayoutGroup] { | |
items | |
} | |
} | |
// MARK: - Section | |
public class LayoutSection { | |
fileprivate var contentInsets: NSDirectionalEdgeInsets = .zero | |
fileprivate var interGroupSpacing: CGFloat = 0 | |
fileprivate var orthogonalScrollingBehavior: UICollectionLayoutSectionOrthogonalScrollingBehavior = .none | |
fileprivate var supplementariesFollowContentInsets: Bool = false | |
fileprivate var visibleItemsInvalidationHandler: NSCollectionLayoutSectionVisibleItemsInvalidationHandler? = nil | |
fileprivate var decorationItems: [NSCollectionLayoutDecorationItem] = [] | |
fileprivate var boundarySupplementaryItems: [NSCollectionLayoutBoundarySupplementaryItem] = [] | |
fileprivate var group: NSCollectionLayoutGroup | |
public init( | |
_ scrollBehavior: UICollectionLayoutSectionOrthogonalScrollingBehavior = .none, | |
@LayoutGroupBuilder groupBuilder: () -> LayoutGroup | |
) { | |
self.orthogonalScrollingBehavior = scrollBehavior | |
self.group = NSCollectionLayoutGroup.convert(from: groupBuilder()) | |
} | |
public func contentInsets(top: CGFloat = 0, leading: CGFloat = 0, bottom: CGFloat = 0, trailing: CGFloat = 0) -> LayoutSection { | |
self.contentInsets = NSDirectionalEdgeInsets(top: top, leading: leading, bottom: bottom, trailing: trailing) | |
return self | |
} | |
public func interGroupSpacing(_ spacing: CGFloat) -> LayoutSection { | |
self.interGroupSpacing = spacing | |
return self | |
} | |
public func supplementariesFollowContentInsets(_ flag: Bool) -> LayoutSection { | |
self.supplementariesFollowContentInsets = flag | |
return self | |
} | |
public func visibleItemsInvalidationHandler(_ handler: @escaping NSCollectionLayoutSectionVisibleItemsInvalidationHandler) -> LayoutSection { | |
self.visibleItemsInvalidationHandler = handler | |
return self | |
} | |
public func decorationItems(@LayoutDecorationItemBuilder _ itemsBuilder: () -> [LayoutDecorationItem]) -> LayoutSection { | |
self.decorationItems = itemsBuilder().map { NSCollectionLayoutDecorationItem.convert(from: $0) } | |
return self | |
} | |
public func decorationItems(@LayoutDecorationItemBuilder _ itemBuilder: () -> LayoutDecorationItem) -> LayoutSection { | |
self.decorationItems = [NSCollectionLayoutDecorationItem.convert(from: itemBuilder())] | |
return self | |
} | |
public func boundarySupplementaryItems(@LayoutBoundarySupplementaryItemBuilder _ itemsBuilder: () -> [LayoutBoundarySupplementaryItem]) -> LayoutSection { | |
self.boundarySupplementaryItems = itemsBuilder().map { NSCollectionLayoutBoundarySupplementaryItem($0) } | |
return self | |
} | |
public func boundarySupplementaryItems(@LayoutBoundarySupplementaryItemBuilder _ itemBuilder: () -> LayoutBoundarySupplementaryItem) -> LayoutSection { | |
self.boundarySupplementaryItems = [NSCollectionLayoutBoundarySupplementaryItem(itemBuilder())] | |
return self | |
} | |
} | |
fileprivate extension NSCollectionLayoutSection { | |
convenience init(_ config: LayoutSection) { | |
self.init(group: config.group) | |
self.boundarySupplementaryItems = config.boundarySupplementaryItems | |
self.contentInsets = config.contentInsets | |
self.decorationItems = config.decorationItems | |
self.interGroupSpacing = config.interGroupSpacing | |
self.orthogonalScrollingBehavior = config.orthogonalScrollingBehavior | |
self.supplementariesFollowContentInsets = config.supplementariesFollowContentInsets | |
self.visibleItemsInvalidationHandler = config.visibleItemsInvalidationHandler | |
} | |
} | |
@_functionBuilder | |
public struct LayoutSectionBuilder { | |
public static func buildBlock(_ items: LayoutSection...) -> [LayoutSection] { | |
items | |
} | |
} | |
// MARK: - Layout | |
public extension UICollectionViewCompositionalLayout { | |
convenience init( | |
scrollDirection: UICollectionView.ScrollDirection = .vertical, | |
@LayoutSectionBuilder sectionBuilder: () -> LayoutSection | |
) { | |
let config = UICollectionViewCompositionalLayoutConfiguration() | |
config.scrollDirection = scrollDirection | |
self.init(section: NSCollectionLayoutSection(sectionBuilder()), configuration: config) | |
} | |
convenience init( | |
scrollDirection: UICollectionView.ScrollDirection = .vertical, | |
sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider | |
) { | |
let config = UICollectionViewCompositionalLayoutConfiguration() | |
config.scrollDirection = scrollDirection | |
self.init(sectionProvider: sectionProvider, configuration: config) | |
} | |
func interSectionSpacing(_ spacing: CGFloat) -> UICollectionViewCompositionalLayout { | |
self.configuration.interSectionSpacing = spacing | |
return self | |
} | |
func boundarySupplementaryItems(@LayoutBoundarySupplementaryItemBuilder _ itemsBuilder: () -> [LayoutBoundarySupplementaryItem]) -> UICollectionViewCompositionalLayout { | |
self.configuration.boundarySupplementaryItems = itemsBuilder().map { NSCollectionLayoutBoundarySupplementaryItem($0) } | |
return self | |
} | |
func boundarySupplementaryItems(@LayoutBoundarySupplementaryItemBuilder _ itemBuilder: () -> LayoutBoundarySupplementaryItem) -> UICollectionViewCompositionalLayout { | |
self.configuration.boundarySupplementaryItems = [NSCollectionLayoutBoundarySupplementaryItem(itemBuilder())] | |
return self | |
} | |
} | |
// MARK:- Helper | |
fileprivate func NSMakeSize(_ widthDimension: NSCollectionLayoutDimension, _ heightDimension: NSCollectionLayoutDimension) -> NSCollectionLayoutSize { | |
NSCollectionLayoutSize(widthDimension: widthDimension, heightDimension: heightDimension) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment