Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Horizontal List Layouts #314

Merged
merged 5 commits into from
Nov 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Added

- [Added support for `.horizontal` `.table` layouts](https://github.com/kyleve/Listable/pull/314). To get a horizontal table; just set the `layout.direction = .horizontal` when configuring your list's layout. Additionally, some properties were renamed from left/right to leading/trailing to better reflect they can now be on the left/top and right/bottom of a list view, respectively.

### Removed

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ extension Appearance
extension LayoutDescription
{
static var demoLayout : Self {
self.demoLayout()
}

static func demoLayout(_ configure : @escaping (inout TableAppearance) -> () = { _ in }) -> Self {
.table {
$0.bounds = .init(
padding: UIEdgeInsets(top: 30.0, left: 20.0, bottom: 30.0, right: 20.0),
Expand All @@ -35,6 +39,10 @@ extension LayoutDescription
itemSpacing: 10.0,
itemToSectionFooterSpacing: 10.0
)

$0.stickySectionHeaders = true

configure(&$0)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ final class CollectionViewBasicDemoViewController : UIViewController

var showsOverscrollFooter : Bool = true
var showsSectionHeaders : Bool = true
var isVertical : Bool = true

let listView = ListView()

Expand All @@ -36,6 +37,7 @@ final class CollectionViewBasicDemoViewController : UIViewController
UIBarButtonItem(title: "UF", style: .plain, target: self, action: #selector(cycleUnderflow)),
UIBarButtonItem(title: "OS", style: .plain, target: self, action: #selector(toggleOverscroll)),
UIBarButtonItem(title: "SH", style: .plain, target: self, action: #selector(toggleSectionHeaders)),
UIBarButtonItem(title: "D", style: .plain, target: self, action: #selector(toggleDirection)),

UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addItem)),
UIBarButtonItem(barButtonSystemItem: .trash, target: self, action: #selector(removeItem)),
Expand All @@ -57,6 +59,10 @@ final class CollectionViewBasicDemoViewController : UIViewController
list.content.overscrollFooter = DemoHeader(title: "Thanks for using Listable!!")
}

list.layout = .demoLayout {
$0.direction = self.isVertical ? .vertical : .horizontal
}

list.animatesChanges = animated

list += self.rows.map { sectionRows in
Expand Down Expand Up @@ -92,6 +98,13 @@ final class CollectionViewBasicDemoViewController : UIViewController
self.updateTable(animated: true)
}

@objc func toggleDirection()
{
self.isVertical.toggle()

self.updateTable(animated: true)
}

@objc func addItem()
{
self.rows[0].insert(DemoItem(text: Date().description), at: 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ final class HorizontalLayoutViewController : UIViewController
self.listView.configure { list in

list.layout = .table {

$0.bounds = .init(padding: UIEdgeInsets(top: 20.0, left: 20.0, bottom: 20.0, right: 20.0))

$0.layout.itemSpacing = 20.0

$0.bounds = .init(
padding: UIEdgeInsets(top: 20.0, left: 20.0, bottom: 20.0, right: 20.0),
width: .atMost(600)
)
}

list.content.overscrollFooter = HeaderFooter(
Expand All @@ -41,58 +43,76 @@ final class HorizontalLayoutViewController : UIViewController
sizing: .fixed(height: 200)
)

Item.list("carousel", sizing: .fixed(height: 200.0)) { horizontal in
Item.list("carousel-paged", sizing: .fixed(height: 200.0)) { horizontal in

horizontal.layout = .paged {
$0.direction = .horizontal
$0.itemInsets = UIEdgeInsets(top: 0.0, left: 20.0, bottom: 0.0, right: 20.0)
}

horizontal += Section(
"cards",
layouts: .init {
$0.table.columns = .init(count: 2, spacing: 20.0)
}
) {
horizontal += Section("cards") {

Item(
CardElement(title: "This is the first card", detail: "Isn't it neat?", color: .white(0.90)),
sizing: .fixed(height: 300)
CardElement(title: "This is the first card in a paged layout", detail: "Isn't it neat?", color: .white(0.90))
)

Item(
CardElement(title: "This is the second card", detail: "Isn't it neat?", color: .white(0.85)),
sizing: .fixed(height: 300)
CardElement(title: "This is the second card", detail: "Isn't it neat?", color: .white(0.85))
)

Item(
CardElement(title: "This is the third card", detail: "Isn't it neat?", color: .white(0.80)),
sizing: .fixed(height: 300)
CardElement(title: "This is the third card", detail: "Isn't it neat?", color: .white(0.80))
)

Item(
CardElement(title: "This is the fourth card", detail: "Isn't it neat?", color: .white(0.75)),
sizing: .fixed(height: 300)
CardElement(title: "This is the fourth card", detail: "Isn't it neat?", color: .white(0.75))
)
}
}

Item.list("carousel-table", sizing: .fixed(height: 200.0)) { horizontal in

horizontal.layout = .table {
$0.direction = .horizontal

$0.layout.itemSpacing = 20.0

$0.bounds = .init(
padding: UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
)
}

horizontal += Section("cards") {

Item(
CardElement(title: "This is the first card in a table layout", detail: "Isn't it neat?", color: .white(0.90)),
sizing: .fixed(width: 200)
)

Item(
CardElement(title: "This is the fifth card", detail: "Isn't it neat?", color: .white(0.70)),
sizing: .fixed(height: 300)
CardElement(title: "This is the second card", detail: "Isn't it neat?", color: .white(0.85)),
sizing: .fixed(width: 200)
)

Item(
CardElement(title: "This is the third card", detail: "Isn't it neat?", color: .white(0.80)),
sizing: .fixed(width: 200)
)

Item(
CardElement(title: "This is the sixth card", detail: "Isn't it neat?", color: .white(0.65)),
sizing: .fixed(height: 300)
CardElement(title: "This is the fourth card", detail: "Isn't it neat?", color: .white(0.75)),
sizing: .fixed(width: 200)
)
}
}

Item(
CardElement(title: "This is the second card", detail: "Isn't it neat?", color: .white(0.95)),
CardElement(title: "This is the fourth card", detail: "Isn't it neat?", color: .white(0.95)),
sizing: .fixed(height: 200)
)

Item(
CardElement(title: "This is the third card", detail: "Isn't it neat?", color: .white(0.95)),
CardElement(title: "This is the fifth card", detail: "Isn't it neat?", color: .white(0.95)),
sizing: .fixed(height: 200)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ final class WidthCustomizationViewController : UIViewController
section.layouts.table.width = .custom(.init(
padding: HorizontalPadding(uniform: 10.0),
width: .atMost(200.0),
alignment: .left
alignment: .leading
)
)

Expand All @@ -78,7 +78,7 @@ final class WidthCustomizationViewController : UIViewController
$0.table.width = .custom(.init(
padding: HorizontalPadding(uniform: 10.0),
width: .atMost(200.0),
alignment: .left
alignment: .leading
)
)
}
Expand All @@ -104,7 +104,7 @@ final class WidthCustomizationViewController : UIViewController
$0.table.width = .custom(.init(
padding: HorizontalPadding(uniform: 10.0),
width: .atMost(200.0),
alignment: .right
alignment: .trailing
)
)
}
Expand Down
2 changes: 1 addition & 1 deletion Internal Pods/Snapshot/Sources/ViewImageSnapshot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public struct ViewImageSnapshot<ViewType:UIView> : SnapshotOutputFormat
public static var outputInfo : SnapshotOutputInfo {
return SnapshotOutputInfo(
directoryName: "Images",
fileExtension: "snapshot.png"
fileExtension: "png"
)
}

Expand Down
8 changes: 3 additions & 5 deletions Internal Pods/Snapshot/Sources/ViewIterations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,19 @@ public struct ViewIteration<ViewType:UIView> : SnapshotIteration

public struct SizedViewIteration<ViewType:UIView> : SnapshotIteration
{
public let name : String
public let size : CGSize

public init(size: CGSize)
public init(name: String = "Snapshot", size: CGSize)
{
self.name = name
self.size = size
}

// MARK: SnapshotIteration

public typealias RenderingFormat = ViewType

public var name : String {
return "\(self.size.width) x \(self.size.height)"
}

public func prepare(render : ViewType) -> ViewType
{
render.frame = CGRect(origin: .zero, size: self.size)
Expand Down
4 changes: 2 additions & 2 deletions Internal Pods/Snapshot/Tests/SnapshotTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ class SnapshotTests : XCTestCase
func test_image_and_text_output()
{
let iterations = [
SizedViewIteration(size: CGSize(width: 200.0, height: 200.0)),
SizedViewIteration(size: CGSize(width: 300.0, height: 300.0)),
SizedViewIteration(name: "200x200", size: CGSize(width: 200.0, height: 200.0)),
SizedViewIteration(name: "300x300", size: CGSize(width: 300.0, height: 300.0)),
]

let snapshot = Snapshot(for: iterations) { iteration in
Expand Down
16 changes: 8 additions & 8 deletions ListableUI/Sources/Layout/Grid/GridListLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public struct GridAppearance : ListLayoutAppearance
constraint : WidthConstraint
) -> CGFloat
{
let paddedWidth = width - padding.left - padding.right
let paddedWidth = width - padding.leading - padding.trailing

return constraint.clamp(paddedWidth)
}
Expand Down Expand Up @@ -280,7 +280,7 @@ final class GridListLayout : ListLayout

let rootWidth = TableAppearance.Layout.width(
with: viewWidth,
padding: HorizontalPadding(left: bounds.padding.left, right: bounds.padding.right),
padding: HorizontalPadding(leading: bounds.padding.left, trailing: bounds.padding.right),
constraint: bounds.width
)

Expand All @@ -298,7 +298,7 @@ final class GridListLayout : ListLayout
performLayout(for: self.content.header) { header in
let hasListHeader = self.content.header.isPopulated

let position = header.layouts.grid.width.position(with: viewSize, defaultWidth: rootWidth)
let position = header.layouts.grid.width.position(with: viewSize.width, defaultWidth: rootWidth)

let measureInfo = Sizing.MeasureInfo(
sizeConstraint: CGSize(width: position.width, height: .greatestFiniteMagnitude),
Expand Down Expand Up @@ -333,7 +333,7 @@ final class GridListLayout : ListLayout

self.content.sections.forEachWithIndex { sectionIndex, isLast, section in

let sectionPosition = section.layouts.grid.width.position(with: viewSize, defaultWidth: rootWidth)
let sectionPosition = section.layouts.grid.width.position(with: viewSize.width, defaultWidth: rootWidth)

//
// Section Header
Expand All @@ -344,7 +344,7 @@ final class GridListLayout : ListLayout

performLayout(for: section.header) { header in
let width = header.layouts.grid.width.merge(with: section.layouts.grid.width)
let position = width.position(with: viewSize, defaultWidth: sectionPosition.width)
let position = width.position(with: viewSize.width, defaultWidth: sectionPosition.width)

let measureInfo = Sizing.MeasureInfo(
sizeConstraint: CGSize(width: position.width, height: .greatestFiniteMagnitude),
Expand Down Expand Up @@ -392,7 +392,7 @@ final class GridListLayout : ListLayout

performLayout(for: section.footer) { footer in
let width = footer.layouts.grid.width.merge(with: section.layouts.grid.width)
let position = width.position(with: viewSize, defaultWidth: sectionPosition.width)
let position = width.position(with: viewSize.width, defaultWidth: sectionPosition.width)

let measureInfo = Sizing.MeasureInfo(
sizeConstraint: CGSize(width: position.width, height: .greatestFiniteMagnitude),
Expand Down Expand Up @@ -433,7 +433,7 @@ final class GridListLayout : ListLayout
performLayout(for: self.content.footer) { footer in
let hasFooter = footer.isPopulated

let position = footer.layouts.grid.width.position(with: viewSize, defaultWidth: rootWidth)
let position = footer.layouts.grid.width.position(with: viewSize.width, defaultWidth: rootWidth)

let measureInfo = Sizing.MeasureInfo(
sizeConstraint: CGSize(width: position.width, height: .greatestFiniteMagnitude),
Expand All @@ -459,7 +459,7 @@ final class GridListLayout : ListLayout

performLayout(for: self.content.overscrollFooter) { footer in

let position = footer.layouts.grid.width.position(with: viewSize, defaultWidth: rootWidth)
let position = footer.layouts.grid.width.position(with: viewSize.width, defaultWidth: rootWidth)

let measureInfo = Sizing.MeasureInfo(
sizeConstraint: CGSize(width: position.width, height: .greatestFiniteMagnitude),
Expand Down
Loading