Skip to content

Commit

Permalink
Support for “Remainder” BrickDimension
Browse files Browse the repository at this point in the history
A Remainder BrickDimension will have a width that is the remainder that is left on a row

Fixes #39
  • Loading branch information
rubencagnie committed Dec 4, 2016
1 parent dfe0610 commit 1d49898
Show file tree
Hide file tree
Showing 12 changed files with 251 additions and 37 deletions.
4 changes: 4 additions & 0 deletions Example/BrickKit-Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
4E3BD8ED1DB521C200541900 /* CoverFlowViewScrollingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3BD8EB1DB521C200541900 /* CoverFlowViewScrollingController.swift */; };
4E8E10F41DB569E100B5BD90 /* EmbeddedSpotlightSnapScrollingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8E10F31DB569E100B5BD90 /* EmbeddedSpotlightSnapScrollingViewController.swift */; };
4E8E10F51DB569E100B5BD90 /* EmbeddedSpotlightSnapScrollingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8E10F31DB569E100B5BD90 /* EmbeddedSpotlightSnapScrollingViewController.swift */; };
932365671DF449A500BE5183 /* RemainderBrickViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 932365661DF449A500BE5183 /* RemainderBrickViewController.swift */; };
9327D03E1DB94A9500D65BCB /* NibLessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9327D03D1DB94A9500D65BCB /* NibLessViewController.swift */; };
9327D03F1DB94A9500D65BCB /* NibLessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9327D03D1DB94A9500D65BCB /* NibLessViewController.swift */; };
9327D0431DB94AB300D65BCB /* NiblessBrick.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9327D0421DB94AB300D65BCB /* NiblessBrick.swift */; };
Expand Down Expand Up @@ -350,6 +351,7 @@
4E3BD8E61DB51E1200541900 /* BrickIdentifiers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrickIdentifiers.swift; sourceTree = "<group>"; };
4E3BD8EB1DB521C200541900 /* CoverFlowViewScrollingController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoverFlowViewScrollingController.swift; sourceTree = "<group>"; };
4E8E10F31DB569E100B5BD90 /* EmbeddedSpotlightSnapScrollingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmbeddedSpotlightSnapScrollingViewController.swift; sourceTree = "<group>"; };
932365661DF449A500BE5183 /* RemainderBrickViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RemainderBrickViewController.swift; sourceTree = "<group>"; };
9327D03D1DB94A9500D65BCB /* NibLessViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibLessViewController.swift; sourceTree = "<group>"; };
9327D0421DB94AB300D65BCB /* NiblessBrick.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NiblessBrick.swift; sourceTree = "<group>"; };
935D488F1DB7CCC70091AA39 /* ImagesInCollectionBrickViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImagesInCollectionBrickViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -624,6 +626,7 @@
4E3BD7A91DB1316400541900 /* SimpleRepeatFixedWidthViewController.swift */,
4E3BD7AA1DB1316400541900 /* SimpleRepeatHeightRatioViewController.swift */,
9327D03D1DB94A9500D65BCB /* NibLessViewController.swift */,
932365661DF449A500BE5183 /* RemainderBrickViewController.swift */,
);
path = Simple;
sourceTree = "<group>";
Expand Down Expand Up @@ -1002,6 +1005,7 @@
4E15F92C1DBA570600BBD363 /* MockTwitterViewController.swift in Sources */,
4E3BD7DE1DB1316400541900 /* SegmentHeaderBrick.swift in Sources */,
4E3BD8261DB1316400541900 /* HideSectionsViewController.swift in Sources */,
932365671DF449A500BE5183 /* RemainderBrickViewController.swift in Sources */,
4E3BD8241DB1316400541900 /* HideBrickViewController.swift in Sources */,
93EAFE2F1DB57D680036331C /* NavigationTransition.swift in Sources */,
4E3BD7D81DB1316400541900 /* PostBrick.swift in Sources */,
Expand Down
47 changes: 47 additions & 0 deletions Example/Source/Examples/Simple/RemainderBrickViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// RemainderBrickViewController.swift
// BrickKit-Example
//
// Created by Ruben Cagnie on 12/4/16.
// Copyright © 2016 Wayfair LLC. All rights reserved.
//

import UIKit
import BrickKit

class RemainderBrickViewController: BrickViewController {
override class var title: String {
return "Remainder Example"
}

override class var subTitle: String {
return "Example of using the Remainder BrickDimension"
}

override func viewDidLoad() {
super.viewDidLoad()

self.registerBrickClass(LabelBrick.self)

self.view.backgroundColor = .brickBackground

let configureCell: (cell: LabelBrickCell) -> Void = { cell in
cell.configure()
}

let section = BrickSection(bricks: [
LabelBrick(width: .Fixed(size: 50), backgroundColor: .brickGray1, text: "BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Remainder, backgroundColor: .brickGray3, text: "BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Remainder, backgroundColor: .brickGray5, text: "BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Fixed(size: 50), backgroundColor: .brickGray2, text: "BRICK", configureCellBlock: configureCell),
BrickSection(width: .Remainder, backgroundColor: .brickGray4, bricks: [
LabelBrick(width: .Ratio(ratio: 0.25), backgroundColor: .brickGray1, text: "BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Remainder, backgroundColor: .brickGray3, text: "BRICK", configureCellBlock: configureCell),
])
], inset: 10, edgeInsets: UIEdgeInsets(top: 20, left: 10, bottom: 20, right: 10))

self.setSection(section)
}

}

14 changes: 7 additions & 7 deletions Example/Source/Examples/Simple/SimpleBrickViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ class SimpleBrickViewController: BrickApp.BaseBrickController {
}

let section = BrickSection(bricks: [
LabelBrick(backgroundColor: .brickGray1, dataSource: LabelBrickCellModel(text: "BRICK 1", configureCellBlock: configureCell)),
LabelBrick(backgroundColor: .brickGray3, dataSource: LabelBrickCellModel(text: "MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK", configureCellBlock: configureCell)),
LabelBrick(width: .Ratio(ratio: 1/2), backgroundColor: .brickGray5, dataSource: LabelBrickCellModel(text: "1/2 BRICK", configureCellBlock: configureCell)),
LabelBrick(width: .Ratio(ratio: 1/2), backgroundColor: .brickGray5, dataSource: LabelBrickCellModel(text: "1/2 BRICK", configureCellBlock: configureCell)),
LabelBrick(width: .Ratio(ratio: 1/3), backgroundColor: .brickGray2, dataSource: LabelBrickCellModel(text: "1/3 BRICK", configureCellBlock: configureCell)),
LabelBrick(width: .Ratio(ratio: 1/3), backgroundColor: .brickGray2, dataSource: LabelBrickCellModel(text: "1/3 BRICK", configureCellBlock: configureCell)),
LabelBrick(width: .Ratio(ratio: 1/3), backgroundColor: .brickGray2, dataSource: LabelBrickCellModel(text: "1/3 BRICK", configureCellBlock: configureCell)),
LabelBrick(backgroundColor: .brickGray1, text: "BRICK 1", configureCellBlock: configureCell),
LabelBrick(backgroundColor: .brickGray3, text: "MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK MULTI-LINE BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Ratio(ratio: 1/2), backgroundColor: .brickGray5, text: "1/2 BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Ratio(ratio: 1/2), backgroundColor: .brickGray5, text: "1/2 BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Ratio(ratio: 1/3), backgroundColor: .brickGray2, text: "1/3 BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Ratio(ratio: 1/3), backgroundColor: .brickGray2, text: "1/3 BRICK", configureCellBlock: configureCell),
LabelBrick(width: .Ratio(ratio: 1/3), backgroundColor: .brickGray2, text: "1/3 BRICK", configureCellBlock: configureCell),
], inset: 10, edgeInsets: UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20))

self.setSection(section)
Expand Down
1 change: 1 addition & 0 deletions Example/Source/Navigation/NavigationDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class NavigationDataSource {
SimpleRepeatFixedWidthViewController.self,
SimpleRepeatFixedHeightViewController.self,
SimpleRepeatHeightRatioViewController.self,
RemainderBrickViewController.self,
MultiSectionBrickViewController.self,
MultiDimensionBrickViewController.self,
]),
Expand Down
4 changes: 2 additions & 2 deletions Source/Layout/BrickFlowLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -324,13 +324,13 @@ extension BrickFlowLayout: BrickLayoutSectionDataSource {
return zIndexBehavior
}

func width(for index: Int, totalWidth: CGFloat, in section: BrickLayoutSection) -> CGFloat {
func width(for index: Int, totalWidth: CGFloat, startingAt origin: CGFloat, in section: BrickLayoutSection) -> CGFloat {
guard let dataSource = dataSource else {
return 0
}

let indexPath = NSIndexPath(forItem: index, inSection: section.sectionIndex)
let width = dataSource.brickLayout(self, widthForItemAtIndexPath: indexPath, totalWidth: totalWidth, widthRatio: widthRatio)
let width = dataSource.brickLayout(self, widthForItemAtIndexPath: indexPath, totalWidth: totalWidth, widthRatio: widthRatio, startingAt: origin)

return width
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Layout/BrickLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ extension BrickLayoutAttributes {
}

public protocol BrickLayoutDataSource: class {
func brickLayout(layout: BrickLayout, widthForItemAtIndexPath indexPath: NSIndexPath, totalWidth: CGFloat, widthRatio: CGFloat) -> CGFloat
func brickLayout(layout: BrickLayout, widthForItemAtIndexPath indexPath: NSIndexPath, totalWidth: CGFloat, widthRatio: CGFloat, startingAt origin: CGFloat) -> CGFloat
func brickLayout(layout: BrickLayout, estimatedHeightForItemAtIndexPath indexPath: NSIndexPath, containedInWidth width: CGFloat) -> CGFloat
func brickLayout(layout: BrickLayout, edgeInsetsForSection section: Int) -> UIEdgeInsets
func brickLayout(layout: BrickLayout, insetForSection section: Int) -> CGFloat
Expand Down
10 changes: 5 additions & 5 deletions Source/Layout/BrickLayoutSection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protocol BrickLayoutSectionDataSource: class {

func edgeInsets(in section: BrickLayoutSection) -> UIEdgeInsets
func inset(in section: BrickLayoutSection) -> CGFloat
func width(for index: Int, totalWidth: CGFloat, in section: BrickLayoutSection) -> CGFloat
func width(for index: Int, totalWidth: CGFloat, startingAt origin: CGFloat, in section: BrickLayoutSection) -> CGFloat
func prepareForSizeCalculation(for attributes: BrickLayoutAttributes, containedIn width: CGFloat, origin: CGPoint, invalidate: Bool, in section: BrickLayoutSection, updatedAttributes: OnAttributesUpdatedHandler?)
func size(for attributes: BrickLayoutAttributes, containedIn width: CGFloat, in section: BrickLayoutSection) -> CGSize
func identifier(for index: Int, in section: BrickLayoutSection) -> String
Expand Down Expand Up @@ -185,7 +185,7 @@ internal class BrickLayoutSection {

invalidateAttributes(attributes[index])

let width = widthAtIndex(index, dataSource: dataSource)
let width = widthAtIndex(index, startingAt: attributes[index].originalFrame.minX - dataSource.edgeInsets(in: self).left, dataSource: dataSource)
let size = dataSource.size(for: attributes[index], containedIn: width, in: self)
attributes[index].originalFrame.size = size
attributes[index].frame.size = size
Expand Down Expand Up @@ -213,11 +213,11 @@ internal class BrickLayoutSection {
}
}

private func widthAtIndex(index: Int, dataSource: BrickLayoutSectionDataSource) -> CGFloat {
private func widthAtIndex(index: Int, startingAt origin: CGFloat, dataSource: BrickLayoutSectionDataSource) -> CGFloat {
let edgeInsets = dataSource.edgeInsets(in: self)
let totalWidth = sectionWidth - edgeInsets.left - edgeInsets.right

return dataSource.width(for: index, totalWidth: totalWidth, in: self)
return dataSource.width(for: index, totalWidth: totalWidth, startingAt: origin, in: self)
}

private func createOrUpdateCells(from firstIndex: Int, invalidate: Bool, updatedAttributes: OnAttributesUpdatedHandler?, customHeightProvider: ((attributes: BrickLayoutAttributes) -> CGFloat?)? = nil) {
Expand Down Expand Up @@ -299,7 +299,7 @@ internal class BrickLayoutSection {
brickAttributes.zIndex = dataSource.zIndex(for: index, in: self)
}

var width = widthAtIndex(index, dataSource: dataSource)
var width = widthAtIndex(index, startingAt: x - edgeInsets.left - origin.x, dataSource: dataSource)

let shouldBeOnNextRow: Bool
switch dataSource.scrollDirection {
Expand Down
18 changes: 14 additions & 4 deletions Source/Models/BrickDimension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extension UIView {
public indirect enum BrickDimension {
case Ratio(ratio: CGFloat)
case Fixed(size: CGFloat)
case Remainder

case Auto(estimate: BrickDimension)
case Orientation(landscape: BrickDimension, portrait: BrickDimension)
Expand Down Expand Up @@ -55,20 +56,26 @@ public indirect enum BrickDimension {
}
}

func value(for otherDimension: CGFloat, in view: UIView) -> CGFloat {
func value(for otherDimension: CGFloat, startingAt origin: CGFloat, in view: UIView) -> CGFloat {
let actualDimension = dimension(in: view)

switch actualDimension {
case .Auto(let dimension): return dimension.value(for: otherDimension, in: view)
default: return BrickDimension._rawValue(for: otherDimension, in: view, with: actualDimension)
case .Auto(let dimension): return dimension.value(for: otherDimension, startingAt: origin, in: view)
default: return BrickDimension._rawValue(for: otherDimension, startingAt: origin, in: view, with: actualDimension)
}
}

/// Function that gets the raw value of a BrickDimension. As of right now, only Ratio and Fixed are allowed
static func _rawValue(for otherDimension: CGFloat, in view: UIView, with dimension: BrickDimension) -> CGFloat {
static func _rawValue(for otherDimension: CGFloat, startingAt origin: CGFloat, in view: UIView, with dimension: BrickDimension) -> CGFloat {
switch dimension {
case .Ratio(let ratio): return ratio * otherDimension
case .Fixed(let size): return size
case .Remainder:
guard otherDimension > origin else {
// If the origin is bigger than the actual dimension, just return the whole dimension
return otherDimension
}
return otherDimension - origin
default: fatalError("Only Ratio and Fixed are allowed")
}
}
Expand Down Expand Up @@ -97,6 +104,9 @@ public func ==(lhs: BrickDimension, rhs: BrickDimension) -> Bool {
case (let .VerticalSizeClass(regular1, compact1), let .VerticalSizeClass(regular2, compact2)):
return regular1 == regular2 && compact1 == compact2

case (.Remainder, .Remainder):
return true

default:
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import Foundation

extension BrickCollectionView: BrickLayoutDataSource {

public func brickLayout(layout: BrickLayout, widthForItemAtIndexPath indexPath: NSIndexPath, totalWidth: CGFloat, widthRatio: CGFloat) -> CGFloat {
public func brickLayout(layout: BrickLayout, widthForItemAtIndexPath indexPath: NSIndexPath, totalWidth: CGFloat, widthRatio: CGFloat, startingAt origin: CGFloat) -> CGFloat {
let inset = self.brickLayout(layout, insetForSection: indexPath.section)
let widthDimension = self.brick(at: indexPath).width

let dimension = widthDimension.dimension(in: self)

switch dimension {
case .Ratio(let ratio): return BrickUtils.calculateWidth(for: ratio, widthRatio: widthRatio, totalWidth: totalWidth, inset: inset)
default: return dimension.value(for: totalWidth, in: self)
default: return dimension.value(for: totalWidth, startingAt: origin, in: self)
}
}

Expand All @@ -38,7 +38,7 @@ extension BrickCollectionView: BrickLayoutDataSource {
}

let heightDimension = brick.height
return heightDimension.value(for: width, in: self)
return heightDimension.value(for: width, startingAt: 0, in: self)
}

public func brickLayout(layout: BrickLayout, edgeInsetsForSection section: Int) -> UIEdgeInsets {
Expand Down
Loading

0 comments on commit 1d49898

Please sign in to comment.