BrickKit is a delightful layout library for iOS and tvOS. It is written entirely in Swift!

Overview

BrickKit

Build Status codecov.io Pod Version Pod Platform Pod License Carthage compatible

BrickKit is a delightful layout library for iOS and tvOS. It is written entirely in Swift!

Deprecated

BrickKit is being phased out at Wayfair, and therefore we will not be maintaining it further.

With BrickKit, you can create complex and responsive layouts in a simple way. It's easy to use and easy to extend. Create your own reusable bricks and behaviors.

Define your layouts using objects that describe the high-level behavior

let section = BrickSection(bricks: [
    LabelBrick(width: .ratio(ratio: 1), text: "BRICK 1"),
    LabelBrick(width: .ratio(ratio: 1), 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"),
    LabelBrick(width: .ratio(ratio: 1/2), text: "1/2 BRICK"),
    LabelBrick(width: .ratio(ratio: 1/2), text: "1/2 BRICK"),
    LabelBrick(width: .ratio(ratio: 1/3), text: "1/3 BRICK"),
    LabelBrick(width: .ratio(ratio: 1/3), text: "1/3 BRICK"),
    LabelBrick(width: .ratio(ratio: 1/3), text: "1/3 BRICK"),
    ], inset: 10, edgeInsets: UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20))

self.setSection(section)

Layout in portrait

Simple Portrait

Layout in landscape

Simple Landscape

Define heights based on rules

// Calculate height using auto-layout
LabelBrick(height: .auto(estimate: .fixed(size: 50)), text: "BRICK"),

// Fixed Height
LabelBrick(height: .fixed(size: 50), text: "BRICK"),

// Calculate height based on ratio of the width
LabelBrick(height: .ratio(ratio: 1), text: "BRICK"),

// Complex Rule based on size classes and/or orientation
let height: BrickDimension =
    .horizontalSizeClass(
        regular: .orientation(
            landscape: .fixed(size: 200),
            portrait: .fixed(size: 100)
        ),
        compact: .orientation(
            landscape: .fixed(size: 100),
            portrait: .fixed(size: 50)
        )
)

Height Ratio portrait

Height Ratio Portrait

Height Ratio landscape

Height Ratio Landscape

Complex layouts, using Sections in Sections

let section = BrickSection(bricks: [
    LabelBrick(width: .ratio(ratio: 0.5), text: "BRICK"),
    BrickSection(width: .ratio(ratio: 0.5), bricks: [
        LabelBrick(text: "BRICK\nBRICK"),
        LabelBrick(text: "BRICK"),
        LabelBrick(text: "BRICK"),
        ], inset: 10),
    BrickSection(bricks: [
        BrickSection(width: .ratio(ratio: 1/3), bricks: [
            LabelBrick(text: "BRICK"),
            LabelBrick(text: "BRICK"),
            ], inset: 5),
        BrickSection(width: .ratio(ratio: 2/3), backgroundColor: .brickGray3, bricks: [
            LabelBrick(text: "BRICK"),
            LabelBrick(text: "BRICK"),
            LabelBrick(text: "BRICK"),
            ], inset: 15),
        ], inset: 5, edgeInsets: UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)),
    BrickSection(width: .ratio(ratio: 0.5), bricks: [
        LabelBrick(text: "BRICK"),
        LabelBrick(text: "BRICK"),
        ], inset: 10),
    LabelBrick(width: .ratio(ratio: 0.5), text: "BRICK"),
    LabelBrick(text: "BRICK"),
    ], inset: 10, edgeInsets: UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20))

self.setSection(section)

Example of Section in Section

Multi Sections

Create your own reuseable Bricks!

registerBrickClass(NiblessBrick.self)

let section = BrickSection(bricks: [
    NiblessBrick(text: "BRICK", image: UIImage(named: "logo_splash")!),
    NiblessBrick(width: .ratio(ratio: 1/2), text: "BRICK", image: UIImage(named: "logo_inapp")!),
    NiblessBrick(width: .ratio(ratio: 1/2), text: "BRICK", image: UIImage(named: "logo_inapp")!)
    ], inset: 10)
setSection(section)

BrickKit supports Bricks with Nibs or Nibsless

Dynamic Sizing

Use different scroll directions within bricks

self.registerBrickClass(CollectionBrick.self)
self.registerBrickClass(LabelBrick.self)

let section1 = BrickSection(bricks: [
    ImageBrick(width: .ratio(ratio: 1/4), height: .ratio(ratio: 1), dataSource: self),
    ] , inset: 10, edgeInsets: UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5))
section1.repeatCountDataSource = self

let section2 = BrickSection(bricks: [
    ImageBrick(width: .ratio(ratio: 1/2), height: .ratio(ratio: 1), dataSource: self),
    ], inset: 10, edgeInsets: UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5))
section2.repeatCountDataSource = self

let section3 = BrickSection(bricks: [
    ImageBrick(width: .fixed(size: 100), height: .ratio(ratio: 1), dataSource: self),
    ], inset: 10, edgeInsets: UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5))
section3.repeatCountDataSource = self

let section = BrickSection(bricks: [
    LabelBrick(text: "1/4 Ratio"),
    CollectionBrick(scrollDirection: .horizontal, dataSource: CollectionBrickCellModel(section: section1), brickTypes: [ImageBrick.self]),
    LabelBrick(text: "1/2 Ratio"),
    CollectionBrick(scrollDirection: .horizontal, dataSource: CollectionBrickCellModel(section: section2), brickTypes: [ImageBrick.self]),
    LabelBrick(text: "100px Fixed"),
    CollectionBrick(scrollDirection: .horizontal, dataSource: CollectionBrickCellModel(section: section3), brickTypes: [ImageBrick.self]),
    ])
setSection(section)

horizontal

Dynamic Image Heights

Images are automatically resized based on its content

registerBrickClass(ImageBrick.self)
registerBrickClass(LabelBrick.self)

let imageURL = NSURL(string:"https://secure.img2.wfrcdn.com/lf/8/hash/2664/10628031/1/custom_image.jpg")!

let section = BrickSection("RootSection", bricks: [
    LabelBrick(text: "Below is an image brick with fixed height"),
    ImageBrick(height: .fixed(size: 50)dataSource: ImageURLBrickModel(url: imageURL, contentMode: .ScaleAspectFit)),
    LabelBrick(text: "Below is an image brick loaded dynamically"),
    ImageBrick(height: .auto(estimate: .fixed(size: 50)), dataSource: ImageURLBrickModel(url: imageURL, contentMode: .ScaleAspectFit)),
    LabelBrick(text: "Below is an image brick with fixed height"),
    ImageBrick(height: .fixed(size: 50), dataSource: ImageURLBrickModel(url: imageURL, contentMode: .scaleAspectFill)),
    ], inset: 10)

self.setSection(section)

images

Advanced Sticky

...
behavior = StickyLayoutBehavior(dataSource: self)
...

func stickyLayoutBehavior(stickyLayoutBehavior: StickyLayoutBehavior, shouldStickItemAtIndexPath indexPath: NSIndexPath, withIdentifier identifier: String, inCollectionViewLayout collectionViewLayout: UICollectionViewLayout) -> Bool {
    return identifier == BrickIdentifiers.titleLabel
}

sticky

Coverflow

layout.scrollDirection = .horizontal

let snapToBehavior = SnapToPointLayoutBehavior(scrollDirection: .horizontal(.Center))
self.brickCollectionView.layout.behaviors.insert(snapToBehavior)
self.brickCollectionView.layout.behaviors.insert(CoverFlowLayoutBehavior(minimumScaleFactor: 0.75))

coverflow

Appear Behavior (none, bottom, top)

layout.appearBehavior = BrickAppearTopBehavior() // Insert from the top
layout.appearBehavior = BrickAppearBottomBehavior() // Insert from the bottom

insert

Spotlight

...
behavior = SpotlightLayoutBehavior(dataSource: self)
...

func spotlightLayoutBehavior(behavior: SpotlightLayoutBehavior, smallHeightForItemAtIndexPath indexPath: NSIndexPath, withIdentifier identifier: String, inCollectionViewLayout collectionViewLayout: UICollectionViewLayout) -> CGFloat? {
    return identifier == BrickIdentifiers.repeatLabel ? 50 : nil
}

spotlight

Features

  • Setup is simple, can create a view with a few lines of code.
  • Is an alternative implementation of a UICollectionViewController.
  • Advanced Width and Height setups, views can be sized according to iPad/screen size upon initialization!
  • Allows for the reuse of cells.
    • Supports multiple nibs per BrickCell: UICollectionViewCell class.
  • Has "behaviors", which are complex layout interactions that can be applied to any view controller.
    • Sticky Headers/Footers
    • Hide Views
    • Scrolling Behaviors
    • Snap to Point
    • These are all supported by ten lines or less of code!
  • Asynchronous changing of height
    • Allows content to flow in after the cell is already on screen.
    • Supports the height of cells to resize after an image or video has loaded.

Installation Instructions

Installation is simple. You just need Cocoapods and it is a matter of adding this to your podfile:

pod 'BrickKit'

See [Installation Details](#Installation Details)

Terminology

Brick

The Brick object represents the model of what needs to be laid out on screen. E.g. in case of a LabelBrick, the model should contain the text that should go inside the label.

We strongly encourage that every Brick has a datasource and an optional delegate. This is a pattern that proves to be successful and allows your brick to be repeated. For simple bricks, it is suggested to create a basic BrickModel that subclasses that datasource, so that you do not have to implement the datasource in the viewcontroller. For a number of examples on how to implement Bricks, refer to the examples in the BrickKit pod, such as LabelBrick or ButtonBrick.

BrickSection

The BrickSection provides information for the BrickCollectionView on how to lay out the cells on screen. In particular, it provides the identifiers, the bricks inside of the BrickSection, as well as UIEdgeInsets and an inset.

A BrickSection is a subclass of a Brick. This provides for nesting of multiple BrickSections inside of a BrickSection. The BrickCollectionView will only accept a single, unified BrickSection, so if you want complex layouts you will want to nest BrickSections together.

BrickCell

The BrickCell object is representing the actual view. The cell will be instantiated when the view comes on screen and will call its dataSource to obtain information on how to display itself.

As BrickKit is based on UICollectionView, every BrickCell is a subclass of UICollectionViewCell.

BrickCollectionView

A BrickCollectionView, a subclass of UICollectionView, manages the brick section/sections. It is also responsible for loading the correct BrickCell for a given brick.

You'll need to register every brick that is used in the BrickCollectionView. (brickCollectionView.registerBrickClass(LabelBrick.self)) If you fail to do so, the app will crash (with a descriptive message) Note, a CollectionBrick is a brick that houses a BrickCollectionView. If you implement one of these, you will have to register the brickClass in the CollectionBrick's BrickCollectionView or you will crash with a nib not found error.

BrickLayout

An object that implements the BrickLayout protocol is responsible for the displaying of the BrickCells on the BrickCollectionView.

BrickFlowLayout

A BrickFlowLayout is an implementation of the BrickLayout protocol.

A BrickFlowLayout is a subclass of a UICollectionViewLayout.

BrickDimension

A BrickDimension is something you provide upon the initialization of a brick. This is where the magic happens. BrickDimensions allow for widths and heights to be based off of view size or a fixed value. Then can then also be dependent on your horizontal or vertical size class, your orientation, or you can simply leave it as automatic and let auto layout do its thing.

BrickRepeatCountDataSource

A BrickRepeatCountDataSource allows you to specify a repeat count for a certain brick. This will give your BrickCell an index, similar to how arrays are setup.

Implementation Details

Ideally, a Brick has an identifier. This identifier can be used to refer back to a certain Brick. The advantage of this over using NSIndexPath is that it decouples the model from the layout. This allows you to use the same brick, datasource, and delegate for a cell.

BrickKit comes with some useful default brick implementations:

The root object used in BrickKit is a BrickSection

The following code will create a label that is:

  • The full width of the view.
  • Its height will dynamically resize based on the text that is inside of the label.
  • The above two conditions are dependent on the nib's constraints being setup correctly, without any specific heights or width set.
 --------------------------------
 |         LABEL BRICK          |
 --------------------------------
import UIKit
import BrickKit

class ViewController: BrickViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let section = BrickSection(bricks: [
            LabelBrick(text: "LABEL BRICK")
            ])

        self.setSection(section)
    }
}

Bricks are sized using auto layout. If the constraints are setup to grow vertically, the brick will get the proper height as needed. So in case of a label, when the text is larger than the width, it will use the next line.

 --------------------------------
 | LABEL BRICK LABEL BRICK LABEL |
 |       BRICK LABEL BRICK       |
 --------------------------------
let section = BrickSection(bricks: [
	LabelBrick(text: "LABEL BRICK LABEL BRICK LABEL BRICK LABEL BRICK")
])

Try it in the LabelBrickPlayground.

BrickDimension

To setup the dimensions of a brick, please refer to BRICK_DIMENSION.md.

BrickRepeatCountDataSource

BrickRepeatCountDataSources are setup based off a section. They can be set upon any BrickSection.

Int { return identifier == "FRUIT" ? fruits.count : 1 } } ">
import UIKit
import BrickKit

class ViewController: BrickViewController {

	var fruits: [Fruit] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        fruits.append(Fruit(name: "Apple"))
        fruits.append(Fruit(name: "Banana"))
        fruits.append(Fruit(name: "Cherry"))

        let section = BrickSection(bricks: [
            LabelBrick("FRUIT", text: "BRICK 1")
        ])

        section.repeatCountDataSource = self

        self.setSection(section)
    }

}

extension ViewController: BrickRepeatCountDataSource {

    func repeatCount(for identifier: String, with collectionIndex: Int, collectionIdentifier: String) -> Int {
        return identifier == "FRUIT" ? fruits.count : 1
    }
}

Try it in the BrickRepeatCountPlayground.

Layout

HideBehavior

This behavior allows you to hide bricks and sections.

BrickAppearBehavior

A behavior that defines the direction where bricks are appearing and disappearing from.

BrickAppearBehavior is extendable, so you can create your own behavior

BrickLayoutZIndexBehavior

A behavior that determines how the bricks are laid out on the z-Axis. This is very important when dealing with behaviors that allow intersections between bricks

Behavior Description
TopDown The cell at the top has the highest zIndex. Ideal for layouts that need Sticky cells, where a Brick needs to be displayed above all other bricks.
BottomUp The cell at the bottom has the highest zIndex. Ideal for layouts where the lower cells are above the higher cells.

Behaviors

A behavior changes the way a brick is displayed on screen. This can depend on scrolling, refreshing etc

BrickKit comes with a few behaviors built in:

Behavior Description
StickyLayoutBehavior Allows bricks and sections to stick to the top of the screen. The brick will stick until its containing section is passed.
MinimumStickyLayoutBehavior Same as the StickyLayoutBehavior, but the height of the brick will first shrink to a minimum value before it starts sticking.
StickyFooterLayoutBehavior Allows bricks and sections to stick to the bottom of the screen. The brick will stick until its containing section is passed.
OnScrollDownStickyLayoutBehavior Same as the StickyLayoutBehavior, but the bricks will only stick when scrolling back up. When scrolling down, the brick will just flow with the other bricks.
SnapToPointLayoutBehavior After scrolling, this behavior will snap your ScrollView to a given location. This is useful if you want bricks to snap to a point after the user is done scrolling.
SpotlightLayoutBehavior While scrolling, the brick 'in the spotlight' will grow. Only one brick is in the spotlight at a time.
CardLayoutBehavior The bricks will scroll like a stack of cards. The ScrollView will not scroll until one card is completely on top of the other.
CoverFlowLayoutBehavior While scrolling, the brick closest to the center of the screen will grow bigger while the other bricks will shrink.
OffsetLayoutBehavior Allows an offset to the origin or size of bricks.
MaxZIndexLayoutBehavior Allows a brick to be set to the maxZIndex, which means they will always be on top of any other brick.
SetZIndexLayoutBehavior Allows the layout to set the ZIndex of any brick to any value.

BrickLayoutBehavior is extendable, so are free to create your own behaviors.

Requirements

  • iOS 9.1+ / tvOS 9.0+
  • Xcode 8.0+
  • Swift 3.0 (Swift 3.2 compatible)

Communication

  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

Installation Details

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate BrickKit into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '' do
    pod 'BrickKit'
end

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate BrickKit into your Xcode project using Carthage, specify it in your Cartfile:

github "wayfair/brickkit-ios"

Run carthage update to build the framework and drag the built BrickKit.framework into your Xcode project.

Credits

BrickKit is owned and maintained by Wayfair.

Code of Conduct

See CODE_OF_CONDUCT.md.

Contributing

See CONTRIBUTING.md.

License

BrickKit is released under the Apache license. See LICENSE for details.

Comments
  • Xcode 9.3/Swift 4.1 upgrade

    Xcode 9.3/Swift 4.1 upgrade

    This is a WIP PR to track necessary configuration and code changes needed to remove warnings from the builds on Xcode 9.3 beta. Initial commit tested with Xcode 9.3 beta 3.

    opened by aaronsky 3
  • Fix severe memory leak when using async resizable cells

    Fix severe memory leak when using async resizable cells

    Previously, the sizeChangedHandler callback set on resizable cells in BrickCollectionView was accidentally capturing a collection cell reference from outside the closure and causing a retain cycle, even though the cell was passed into the closure as an argument. This change resolves that issue so that the argument is referenced instead of any captured variables.

    This also includes a test to ensure that the collection cell is deallocated properly if the brick collection view that owns it is also deallocated. I needed to make a new test async cell since the existing one uses an NSTimer which interferes with the deinitialization in ways I don't fully understand.

    I recommend releasing a new version of BrickKit as soon as this is merged since this can leak a lot of memory, especially if the async brick is a collection brick containing child collection views/cells.

    opened by klundberg 3
  • GenericBrick

    GenericBrick

    Introduction of a GenericBrick, that allows to wrap any UIView in a Brick.

    This will allow a straight forward syntax:

    GenericBrick<UILabel>(GenericLabelBrickIdentifier, size: BrickSize(...)) { label, cell in
                label.text = "LABEL " + String(cell.index)
                cell.edgeInsets = UIEdgeInsets(top: 5, left: 10, bottom: 15, right: 20)
            }
    

    Fixes #64

    opened by rubencagnie 3
  •  compiled with older version of Swift language

    compiled with older version of Swift language

    BrickKit.framework/BrickKit compiled with older version of Swift language (2.0) than previous files (3.0) for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

    how can i slove this

    thank you

    opened by Alfulayt 3
  • Stability, Layout, and Logging Enhancements; Added Support for Legacy Edge Insets Functionality

    Stability, Layout, and Logging Enhancements; Added Support for Legacy Edge Insets Functionality

    • Includes a fix (and unit tests) for the crashes that occur due to changing repeat counts. @rubencagnie has looked at this change and agreed it looks good.

    • Add the flag needsLegacyEdgeInsetFunctionality to BrickCell, which defaults to false, but can be set to true if the legacy handling of edge insets is required.

    • Remove some forced unwraps in BrickFlowLayout to avoid crashes.

    • Fix a crash that could occur due to calculating layouts of deleted sections in BrickFlowLayout.

    • Refactor Height provider to be a closure instead of protocol.

    • Fix a crash due to unchecked bounds of a range creation in BrickLayoutSection

    • Clear prefetch index paths upon invalidation.

    • Add additional verbose logging to refresh/reloading of data.


    Squashed Commit of the following:

    commit 89ef6504e274549938f5d31e1bd9b0b62a697f86 Author: Will Spurgeon [email protected] Date: Thu Nov 9 10:16:10 2017 -0500

    Added additional verbose logging to refresh/reloading of data.
    

    commit cee70e8c30e49340121449cdab8be3ad630e0f0e Author: Will Spurgeon [email protected] Date: Thu Nov 2 15:05:39 2017 -0400

    Clear prefetch index paths upon invalidation. Written by nlobue
    

    commit c760425a459137070951bb2fb62a139d8e5739ae Author: Will Spurgeon [email protected] Date: Mon Oct 30 16:50:56 2017 -0400

    Fix for a crash that can occur if the first index is greater the number of items.
    

    commit a838e8ddcc3ce8344cf7b49773eb6ff68f4532b7 Author: Will Spurgeon [email protected] Date: Mon Oct 23 14:15:58 2017 -0400

    Updated height provider code to be a closure (#191). Fix by vlozko.
    

    commit 5e21936360b3824bd755dc0acf293242129f065f Author: Will Spurgeon [email protected] Date: Wed Oct 18 14:06:09 2017 -0400

    Fix for crash
    

    commit 48846eed8902b2ad93483c4f10ee478ce1219ee4 Author: Will Spurgeon [email protected] Date: Fri Oct 13 10:04:59 2017 -0400

    Attempt to fix a crash
    

    commit e6d3c6d55c4fb9792aa5a55cf5682bc4145e072d Author: Will Spurgeon [email protected] Date: Thu Oct 5 17:28:58 2017 -0400

    Added a flag that determines which version of the inset updating code is run.
    
    opened by mamccarthy 2
  • Support for Drag and Drop

    Support for Drag and Drop

    This pull request is a Work In Progress and should not be merged until otherwise noted!!

    This PR introduces drag and drop support to BrickKit.

    Bricks that should be considered eligible for drag and/or drop should provide a delegate for Brick#dragDropDelegate. To opt-in to drag, return a [UIDragItem] in BrickDragDropDelegate#dragItems(for:at:). To opt-in to drop, return a Bool in BrickDragDropDelegate#canHandle(_:) affirming whether the provided UIDropSession has any objects that conform to your brick's supported UTIs, and implement the BrickDragDropDelegate#willDrop(_) and BrickDragDropDelegate#drop(_:to:from:) handlers. For more information, see the DragDropBrickViewController example, as well as Apple's documentation on Drag and Drop in Collection Views.

    I have put this PR up here despite its state of completion to kickstart discussion about this feature, as well as provide advice on how BrickLayouts work.

    Current list of to-dos:

    • [ ] Fix current blocking crashers
      • [ ] Sample app crashes while attempting to reorder layout while previous drop has not completed
      • [ ] Sample app crashes while attempting to reorder layout to accommodate new cells
    • [ ] Document all new methods and protocols
    • [ ] Implement drag and drop in other example controllers to demonstrate drag and drop between collection views within the same app
    • [ ] Write lots of unit tests
    opened by aaronsky 2
  • Revert

    Revert "Fixed performance of height recalculation"

    Reverts wayfair/brickkit-ios#180

    PR #180 seemed to create some issues with height calculations, creating jankyness on some screens. Reverting for now.

    opened by wfsttam 2
  • Varadic range support

    Varadic range support

    Allows the BrickKit collection view controller to apply different dimensions based upon how wide the brick is. Starting with a minimum dimension that would be applicable to all widths, the app can the specify different dimensions for any additional widths.

    100% code coverage for all additional code. Added code to sample app to demonstrate support for it.

    opened by vlozko 2
  • Height Calculation Issue using CollectionBrick for a carousel

    Height Calculation Issue using CollectionBrick for a carousel

    A chunk of blank space appears when above the space I use a collection brick to create a carousel. Invalidating the brick collection view will fix the problem and the missing bricks will appear and the height will get calculated properly.

    opened by wfsttam 2
  • Xcode 11 compatibility

    Xcode 11 compatibility

    • remove some deprecated behaviors that no longer work properly
    • avoid touching contentInsets on the collection view when possible — this can cause an infinite loop on iOS 13
    • add some floating point slop to the comparison where we decide whether or not to invalidate. Auto layout is giving us back some slightly different values when running against the iOS 13 SDK and otherwise we sometimes end up in an infinite layout loop
    opened by peter-tomaselli 1
  • Push 2.4.2 to trunk to enable use of Swift 4.0 compatible BrickKit in podspec

    Push 2.4.2 to trunk to enable use of Swift 4.0 compatible BrickKit in podspec

    It appears that only minor versions are being pushed to CocoaPods/Specs https://github.com/CocoaPods/Specs/search?q=BrickKit&type=Commits

    Could you consider pushing 2.4.2 to the trunk as an exception?

    I'd like to use BrickKit as a dependency in a podspec I am creating, but am currently limited to using 2.4.0 which is not Swift 4.0 compatible. Since podspecs don't currently support a mix of Swift 3.2/4.0 (https://github.com/CocoaPods/CocoaPods/issues/7134) the podspec can only use Swift 3.2 pod dependencies if BrickKit is included.

    While a Podfile can specify a pod that is not yet pushed to the trunk (using :git and :tag), a podspec cannot do the same with a dependency.

    Thanks for considering this request.

    opened by scottcarter 1
  • Brick height depending of the View height

    Brick height depending of the View height

    I saw in the readme that there are 3 different ways to define height.

    // Calculate height using auto-layout
    LabelBrick(height: .auto(estimate: .fixed(size: 50)), text: "BRICK"),
    
    // Fixed Height
    LabelBrick(height: .fixed(size: 50), text: "BRICK"),
    
    // Calculate height based on ratio of the width
    LabelBrick(height: .ratio(ratio: 1), text: "BRICK")
    

    However I did not see a way to set the height depending on the superView height (like there is for the width). For instance, if I want to have cells being a third of the height, I do not know how to proceed : I can update the section in viewWillTransitionTo() but I would like not to use this ugly solution

    opened by Stanou01260 0
  • `StickyFooterLayoutBehavior` leads to incorrect layout of surrounding bricks

    `StickyFooterLayoutBehavior` leads to incorrect layout of surrounding bricks

    Applying StickyFooterLayoutBehavior to a brick inside of a BrickSection leads to incorrect layout of the surrounding bricks, particularly when a CollectionBrick is also involved.

    opened by peter-tomaselli 0
  • Index out of bounds exception in ReorderableBrickViewController.swift:107 test method

    Index out of bounds exception in ReorderableBrickViewController.swift:107 test method

    On branch master, tag v2.4.1, current as of commit 8d815f019e3a9b90cdfcbcc7933010854661f94b

    Steps to Reproduce

    • clone master
    • open the .xcworkspace
    • build and run the example app target, BrickApp-iOS
    • from the list of samples, select SIMPLE
    • in the SIMPLE list of samples, scroll down and select Reorderable Section
    • in Reorderable Section, click the + icon in the top right

    Expected Result

    The Xcode debugger console should print the section titles and bricks in each section.

    Actual Result

    Section: 0 // text omitted Section: 1 Label 1 Index 0: 0 Label 1 Index 1: 2 fatal error: Index out of range 2017-10-04 20:14:19.723618-0400 BrickApp[34526:35108613] fatal error: Index out of range

    Exception produced is at ReorderableBrickViewController.swift:107 but would also occur at line 111

    opened by pdtgct 1
  • Insets based of size class

    Insets based of size class

    We should add a way of specifying insets based off size class because the current way is to do something like BrickSection(bricks: [...], inset: self.traitCollection.horizontalSizeClass == .compact ? 0 : 8). We should do something like Brick Dimension.

    opened by jay18001 0
  • Add prepareForReuse functions to ButtonBrickCell and LabelBrickCell

    Add prepareForReuse functions to ButtonBrickCell and LabelBrickCell

    These brick cells should prepare themselves for reuse. Otherwise, large brick collections with many instances of these bricks would need to properly set over a dozen properties in each configure method. A number of properties on both brick cells have generally assumed "default states". I.E. It should be safe to assume that a LabelBrickCell passed into a configure method does not have its textAlignment property set to .right.

    opened by willspurgeon 0
Releases(v.2.6.0)
Owner
Wayfair Tech – Archive
Furnishing the future of technology with Wayfair, your destination for a zillion things home.
Wayfair Tech – Archive
LayoutKit is a fast view layout library for iOS, macOS, and tvOS.

?? UNMAINTAINED ?? This project is no longer used by LinkedIn and is currently unmaintained. LayoutKit is a fast view layout library for iOS, macOS, a

LinkedIn's Attic 3.2k Dec 27, 2022
LayoutKit is a fast view layout library for iOS, macOS, and tvOS.

?? UNMAINTAINED ?? This project is no longer used by LinkedIn and is currently unmaintained. LayoutKit is a fast view layout library for iOS, macOS, a

LinkedIn's Attic 3.2k Jan 4, 2023
Auto Layout (and manual layout) in one line.

Auto Layout (and manual layout) in one line. Quick Look view.bb.centerX().below(view2).size(100) It’s equivalent to iOS 9 API: view.centerXAnchor.cons

Javier Zhang 74 Oct 19, 2022
Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [iOS/macOS/tvOS/CALayer]

Extremely Fast views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainabl

layoutBox 2.1k Dec 22, 2022
AppStoreClone - Understanding the complex layout of app store using UICompositional layout in swift

AppStoreClone Understanding the complex layout of app store using UICompositiona

Dheeraj Kumar Sharma 8 Dec 28, 2022
Auto Layout made easy with the Custom Layout.

Auto Layout made easy with the Custom Layout. Getting started CocoaPods CocoaPods is a dependency manager for Cocoa projects. You can install it with

Malith Nadeeshan 1 Jan 16, 2022
A custom layout built on top of SwiftUI's Layout API that lays elements out in multiple lines. Similar to flex-wrap in CSS, CollectionViewFlowLayout.

WrapLayout A custom layout built on top of SwiftUI's Layout API that lays elements out in multiple lines. Similar to flex-wrap in CSS, CollectionViewF

Hiroshi Kimura 6 Sep 27, 2022
Written in pure Swift, QuickLayout offers a simple and easy way to manage Auto Layout in code.

QuickLayout QuickLayout offers an additional way, to easily manage the Auto Layout using only code. You can harness the power of QuickLayout to align

Daniel Huri 243 Oct 28, 2022
A Code challenge I solved leveraging a lot on Composite collection view layout written in swift

AsthmApp Mobile app designed as a support aid for people with Asthma Accounts Google and Firebase [email protected] dICerytiMPSI Facebook asthmp.ap

null 0 Dec 13, 2021
A Code challenge I solved leveraging a lot on Composite collection view layout...written in swift

Space44 Code Challenge Space44 Code Challenge iOS application for Space 44 hiring process, it leverages on Image download and composite collection vie

null 0 Dec 16, 2021
✂ Easy to use and flexible library for manually laying out views and layers for iOS and tvOS. Supports AsyncDisplayKit.

ManualLayout Table of Contents Installation Usage API Cheat Sheet Installation Carthage Add the following line to your Cartfile. github "isair/ManualL

Baris Sencan 280 Sep 29, 2022
Intuitive and powerful Auto Layout library

Align introduces a better alternative to Auto Layout anchors. Semantic. Align APIs focus on your goals, not the math behind Auto Layout constraints. P

Alexander Grebenyuk 338 Oct 18, 2022
SuperLayout is a Swift library that makes using Auto Layout a breeze.

SuperLayout is a library that adds a few custom operators to Swift that makes using the amazing NSLayoutAnchor API for Auto Layout a breeze. SuperLayo

Lionheart Software 53 Oct 12, 2022
Harness the power of AutoLayout NSLayoutConstraints with a simplified, chainable and expressive syntax. Supports iOS and OSX Auto Layout

Masonry Masonry is still actively maintained, we are committed to fixing bugs and merging good quality PRs from the wider community. However if you're

null 18k Jan 5, 2023
An easy way to create and layout UI components for iOS (Swift version).

Introduction Cupcake is a framework that allow you to easily create and layout UI components for iOS 8.0+. It use chaining syntax and provides some fr

nerdycat 288 Oct 9, 2022
The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. Objective-C and Swift compatible.

The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. PureLayout extends UIView/NSView, NSArray, and NSLayoutConstrai

PureLayout 7.6k Jan 6, 2023
A collection of operators and utilities that simplify iOS layout code.

Anchorage A lightweight collection of intuitive operators and utilities that simplify Auto Layout code. Anchorage is built directly on top of the NSLa

Rightpoint 620 Jan 3, 2023
MyLayout is a simple and easy objective-c framework for iOS view layout

MyLayout is a powerful iOS UI framework implemented by Objective-C. It integrates the functions with Android Layout,iOS AutoLayout,SizeClass, HTML CSS float and flexbox and bootstrap. So you can use LinearLayout,RelativeLayout,FrameLayout,TableLayout,FlowLayout,FloatLayout,PathLayout,GridLayout,LayoutSizeClass to build your App 自动布局 UIView UITableView UICollectionView RTL

欧阳大哥2013 4.2k Dec 30, 2022
Declarative Auto Layout in Swift, clean and simple

Tails Tails is a take on declarative Auto Layout. If you don't like typing (like me), it might be your kind of thing! Tails is written in Swift and cu

Nick Tymchenko 17 Jan 31, 2019