A mosaic collection view layout inspired by Lightbox's Algorithm, written in Swift 🔶

Overview

TRMosaicLayout

CI Status codebeat badge Version License Platform

A mosaic collection view layout inspired by Lightbox's Algorithm. This is a swift implementation/extension of @fmitech's FMMosaicLayout. The standard UICollectionViewFlowLayout can be a boring presentation in your app, but TRMosaicLayout is a simple feature that will engage your users with your eyecatching content. If you don't believe me, checkout Snapchat's app and their awesome layout in their Discover feed.

TRMosaicLayout implementation

Similar implementation used by @snapchat

Why use this

  • TRMosaicLayout is great for displaying images that are in portrait or have a similar aspect ratio
  • Examples
    • Movie posters
    • Book covers
    • Magazines
    • News articles

Installation

CocoaPods

You can use CocoaPods to install TRMosaicLayout by adding it to your Podfile:

platform :ios, '8.0'
use_frameworks!
pod 'TRMosaicLayout'

Then, import TRMosaicLayout

import TRMosaicLayout

Manually

  1. Download and drop /TRMosaicLayoutfolder in your project.
  2. Congratulations!

Implementation

Create a subclass of UICollectionViewController

import TRMosaicLayout

class TRCollectionViewController: UICollectionViewController {
  override func viewDidLoad() {
    super.viewDidLoad()

      let mosaicLayout = TRMosaicLayout()
      self.collectionView?.collectionViewLayout = mosaicLayout
      mosaicLayout.delegate = self
  }
}

Extend your subclass of UICollectionViewController with TRMosaicLayoutDelegate

extension TRCollectionViewController: TRMosaicLayoutDelegate {

  func collectionView(collectionView:UICollectionView, mosaicCellSizeTypeAtIndexPath indexPath:NSIndexPath) -> TRMosaicCellType {
    // I recommend setting every third cell as .Big to get the best layout
    return indexPath.item % 3 == 0 ? TRMosaicCellType.Big : TRMosaicCellType.Small
  }

  func collectionView(collectionView:UICollectionView, layout collectionViewLayout: TRMosaicLayout, insetAtSection:Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)
  }

  func heightForSmallMosaicCell() -> CGFloat {
    return 150
  }
}

Troubleshooting

The cell's aren't aligned properly

  • Make sure the views you are adding to the cell have the correct frame
  let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath)
  let imageView = UIImageView(image: image)
  imageView.frame = cell.frame
  cell.backgroundView = imageView
  return cell

Getting a nil while unwrapping error

  • Make sure you set the delegate of TRMosaicLayout to your collectionViewController
  • mosaicLayout.delegate = self

Something else isn't working properly

  • Use github's issue reporter on the right, this will you be your best bet as I'm on Github fairly regularly
  • Send me an email [email protected]

Release History

  • 1.0.0 Update to Swift 3
  • 0.1.0 First release on CocoaPods

Contributions

I am happy to accept any open contributions. Just fork this project, make the changes and submit a pull request.

Author

Vincent Le, [email protected]

License

TRMosaicLayout is available under the MIT license. See the LICENSE file for more info.

Comments
  • Doesn't scroll when big one cell alone

    Doesn't scroll when big one cell alone

    Hello, found that problem, what is this? my mistake? Scrolling just stop, if there big one cell without 2 small, but i can see it while bouncing collectionview I like your job, and want to implement in my project, but does it work only with even counts of items?

    bug 
    opened by vadimvitvickiy 11
  • swift 3 implementation

    swift 3 implementation

    swift 3 version (ios10) xcode 8 beta6, compiled with COCOAPODS: 1.1.0.beta.2

    it compiles, runs, images are shown, but scrolling breaks app.

    This is my first pull request, I hope I do it right

    Stacktrace tail:

    Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.5/UICollectionViewData.m:709
    2016-09-08 17:37:02.006 TRMosaicLayout_Example[58384:4207508] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath: <NSIndexPath: 0x610000036f60> {length = 2, path = 0 - 12}'
    *** First throw call stack:
    (
        0   CoreFoundation                      0x000000010cdf334b __exceptionPreprocess + 171
        1   libobjc.A.dylib                     0x000000010c85421e objc_exception_throw + 48
        2   CoreFoundation                      0x000000010cdf7442 +[NSException raise:format:arguments:] + 98
        3   Foundation                          0x000000010c3eaedd -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
        4   UIKit                               0x000000010db9ff70 -[UICollectionViewData layoutAttributesForItemAtIndexPath:] + 670
        5   UIKit                               0x000000010db4df0a -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 384
        6   UIKit                               0x000000010db4e9db -[UICollectionView dequeueReusableCellWithReuseIdentifier:forIndexPath:] + 169
        7   TRMosaicLayout_Example              0x000000010c1b782e _TFC22TRMosaicLayout_Example26TRCollectionViewController14collectionViewfTCSo16UICollectionView13cellForItemAtV10Foundation9IndexPath_CSo20UICollectionViewCell + 206
        8   TRMosaicLayout_Example              0x000000010c1b7df7 _TToFC22TRMosaicLayout_Example26TRCollectionViewController14collectionViewfTCSo16UICollectionView13cellForItemAtV10Foundation9IndexPath_CSo20UICollectionViewCell + 87
        9   UIKit                               0x000000010db39b27 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 467
        10  UIKit                               0x000000010db3b71c -[UICollectionView _prefetchItemsForVelocity:maxItemsToPrefetch:invalidateCandidatesOnDirectionChanges:] + 398
        11  UIKit                               0x000000010db44c4e -[UICollectionView layoutSubviews] + 717
        12  UIKit                               0x000000010d2daae4 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1237
        13  QuartzCore                          0x000000011316fcdc -[CALayer layoutSublayers] + 146
        14  QuartzCore                          0x00000001131637a0 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
        15  QuartzCore                          0x000000011316361e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
        16  QuartzCore                          0x00000001130f162c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 280
        17  QuartzCore                          0x000000011311e713 _ZN2CA11Transaction6commitEv + 475
        18  QuartzCore                          0x000000011311f083 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 113
        19  CoreFoundation                      0x000000010cd97e17 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
        20  CoreFoundation                      0x000000010cd97d87 __CFRunLoopDoObservers + 391
        21  CoreFoundation                      0x000000010cd7cb9e __CFRunLoopRun + 1198
        22  CoreFoundation                      0x000000010cd7c494 CFRunLoopRunSpecific + 420
        23  GraphicsServices                    0x000000011297fa6f GSEventRunModal + 161
        24  UIKit                               0x000000010d216a74 UIApplicationMain + 159
        25  TRMosaicLayout_Example              0x000000010c1b994f main + 111
        26  libdyld.dylib                       0x00000001108e068d start + 1
        27  ???                                 0x0000000000000001 0x0 + 1
    )
    libc++abi.dylib: terminating with uncaught exception of type NSException
    (lldb) 
    
    opened by exocode 6
  • Collection view isn't scrolling to the last item if the item count is not divisible by 3

    Collection view isn't scrolling to the last item if the item count is not divisible by 3

    Hi,

    Your library is great! Just found out that collection view isn't scrolling to the last item if the item count is not divisible by 3..it happens in your example code too.. Could you please fix it?

    Thanks

    bug 
    opened by lennathe 3
  • custom layout not attached

    custom layout not attached

    Hi there,

    I am sorry, to maybe ask a stupid question.

    I've installed all proberly. The demo is running nicely with the Asset book images. (y)

    Now my problem:

    I installed TRMosaikLayout by cocoapods. I am using XCode8 beta6. I copied the TRCollectionViewController code into an empty UICollectionViewController class. I added a UICollectionViewController onto my storyboard I changed the reuseIdentifier to the proberly name Added the Assets you provide in your example I changed the cell color to any color (for testing) Run the project, but cellForItemAt indexPathwas never called.

    After a few hours of doom, I commented out the

       ` // self.collectionView!.collectionViewLayout = mosaicLayout`
    

    Now it shows me the cells regularly. But not as Mosaiks. When I comment in this line, the mosaiklayout stays empty.

    The cellForItemAt indexPath function don't get called.

    What I am missing, what should I do?

    Many thanks in advance

    bug 
    opened by exocode 2
  • Add Objective-C compatibility

    Add Objective-C compatibility

    Changes

    • add @objc prefix to protocol and enum
    • add type to the enum

    Would be great to prepare whole library little bit better for Obj-C so anybody can use it.

    Thanks for merging ASAP so we don't need to use our forks @vinnyoodles. :)

    EDIT: Also updated example project, fixed cocoapods and some other improvements.

    opened by Kaspik 0
  • Would a binary search be quicker then a linear search in layoutAttributesForElements?

    Would a binary search be quicker then a linear search in layoutAttributesForElements?

    I was watching the latest WWDC and they had a section called "A Tour of UICollectionView". In this section, the instructor creates a mosaic layout like yours by creating a subclass of UICollectionViewLayout just like TRMosaicLayout. Yet the instructor optimizes the layout for scrolling within the layoutAttributesForElements by changing the method from a linear search to a binary. Binary searches are somewhat new to me, so after rewatching the video and doing some research, I found the collection needs to be sorted to be able to run a binary search. My problem is I get a bit confused on how to create the binary search and if your cachedCellLayoutAttributes are sorted already. In the video the instructor says the cachedCallLayoutAttributes are sorted by there frames minimum y value, yet when i debug cachedCellLayoutAttributes it seems that the there frames minimum y value isn't sorted. If you have any ideas or if its even worth doing in the first place let me know. I'll add video link and specific time of video below.

    https://developer.apple.com/videos/play/wwdc2018/225/ Specific time about optimization within layoutAttributesForElements: 25:40 -> 28:00

    opened by stshelton 0
  • Retain cycle on TRMosaicLayoutDelegate

    Retain cycle on TRMosaicLayoutDelegate

    The following delegate should be weak: open var delegate: TRMosaicLayoutDelegate! Being a strong reference lead to a retain cycle on any controller using this delegate.

    I will propose a PR soon to fix this if you don't mind.

    opened by Drusy 0
  • UIEdgeInsets is not working properly

    UIEdgeInsets is not working properly

    It seems the right inset is not as large as what it should be. I set the same value as the left and right insets. But the right displayed inset is smaller than the left.

    opened by mbt925 1
  • Footer Not Displayed After using TRMosaicLayout

    Footer Not Displayed After using TRMosaicLayout

    This is a superb layout library, but I am facing a serious problem.

    collectionView.register(UINib(nibName: "LoadingFooterCollectionReusableView", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "loadingFooterIdentifier");

    //The delegate function below is no longer called func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { }

    
    Any ideas how to fix this? 
    opened by Jayvd 3
Owner
Vincent Le
Vincent Le
An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations :large_orange_diamond:

SquareMosaicLayout An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations. Note This layout is not of waterfall

Mikhail Vasilev 254 Dec 6, 2022
BouncyLayout is a collection view layout that makes your cells bounce.

BouncyLayout is a collection view layout that makes your cells bounce. Features Pure Swift 5. Works with every UICollectionView. Horizontal and vertic

Robert-Hein Hooijmans 4.2k Jan 3, 2023
Blueprints - A framework that is meant to make your life easier when working with collection view flow layouts.

Description Blueprints is a collection of flow layouts that is meant to make your life easier when working with collection view flow layouts. It comes

Christoffer Winterkvist 982 Dec 7, 2022
UICollectionViewSplitLayout makes collection view more responsive.

UICollectionViewSplitLayout makes collection view more responsive. What's this? UICollectionViewSplitLayout is a subclass of UICollectionViewLayout. I

Yahoo! JAPAN 239 Dec 6, 2022
A bunch of layouts providing light and seamless experiences in your Collection View

Swinflate Description Swinflate aims to encorporate a set of collection view layouts which provide a better and even more fluid experience in collecti

Vlad Iacob 224 Dec 19, 2022
The waterfall (i.e., Pinterest-like) layout for UICollectionView.

CHTCollectionViewWaterfallLayout CHTCollectionViewWaterfallLayout is a subclass of UICollectionViewLayout, and it trys to imitate UICollectionViewFlow

Nelson 4.4k Dec 24, 2022
A CollectionView Layout displaying a slanted cells

CollectionViewSlantedLayout is a subclass of the UICollectionViewLayout allowing the display of slanted cells in a UICollectionView. Features Pure Swi

Yassir Barchi 2.2k Dec 27, 2022
AZSafariCollectionViewLayout is replica of safari browser history page layout. very easy to use, IBInspectable are given for easy integration

AZSafariCollectionViewLayout Features iOS Safari history view layout IBDesignAble for properties Few minutes integration Installation CocoaPods CocoaP

Afroz Zaheer 211 Dec 6, 2022
A lightweight UICollectionViewLayout that 'pages' and centers its cells 🎡 written in Swift

CenteredCollectionView CenteredCollectionView is a lightweight drop in place UICollectionViewFlowLayout that pages and keeps its cells centered, resul

Ben Emdon 1.2k Dec 6, 2022
A drop-in mosaic collection view layout with a focus on simple customizations.

FMMosaicLayout is a mosiac collection view layout. There are a great number of media-based iOS applications that use UICollectionViewFlowLayout withou

Fluid Media Inc. 591 Dec 14, 2022
An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations :large_orange_diamond:

SquareMosaicLayout An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations. Note This layout is not of waterfall

Mikhail Vasilev 254 Dec 6, 2022
💻 A fast and flexible O(n) difference algorithm framework for Swift collection.

A fast and flexible O(n) difference algorithm framework for Swift collection. The algorithm is optimized based on the Paul Heckel's algorithm. Made wi

Ryo Aoyama 3.3k Jan 4, 2023
💻 A fast and flexible O(n) difference algorithm framework for Swift collection.

A fast and flexible O(n) difference algorithm framework for Swift collection. The algorithm is optimized based on the Paul Heckel's algorithm. Made wi

Ryo Aoyama 3.3k Jan 4, 2023
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
Modern-collection-view - Modern collection view for swift

Modern collection view Sample application demonstrating the use of collection vi

Nitanta Adhikari 1 Jan 24, 2022
Simplex-Swift - A basic implementation of the Simplex algorithm, written in Swift

Simplex-Swift - A basic implementation of the Simplex algorithm, written in Swift

Evgeny Seliverstov 5 Dec 20, 2022
Lightweight custom collection view inspired by Airbnb.

ASCollectionView Lightweight custom collection view inspired by Airbnb. Screenshots Requirements ASCollectionView Version Minimum iOS Target Swift Ver

Abdullah Selek 364 Nov 24, 2022
Lightweight custom collection view inspired by Airbnb.

ASCollectionView Lightweight custom collection view inspired by Airbnb. Screenshots Requirements ASCollectionView Version Minimum iOS Target Swift Ver

Abdullah Selek 364 Nov 24, 2022
A fancy collection style view controller that was inspired by this Profile Card mockup

JFCardSelectionViewController A fancy collection style view controller that was inspired by this Profile Card mockup: https://dribbble.com/shots/14584

Jeremy Fox 430 Dec 5, 2022