Giter Site home page Giter Site logo

antondomashnev / admozaiccollectionviewlayout Goto Github PK

View Code? Open in Web Editor NEW
226.0 11.0 35.0 25.32 MB

ADMozaicCollectionViewLayout is yet another UICollectionViewLayout subclass that implements "brick", "mozaic" or Pinterest style layout.

License: MIT License

Objective-C 0.47% Swift 96.33% Ruby 3.20%
uicollectionview uicollectionviewlayout mozaic waterfall carthage cocoapods

admozaiccollectionviewlayout's Introduction

ADMozaicCollectionViewLayout

Carthage compatible CocoaPods Compatible codebeat badge

What is it

ADMozaicCollectionViewLayout is yet another UICollectionViewLayout subclass that implements "brick" or "mozaic" layout.

example

Why do anybody need yet another one?

Because there are plenty of kind of the same layouts already:

But this project is pure swift implementation, so if you don't want to mess up objective-c code and swift you are on the right page. Also, as an advantage compares to another "mozaic" layout - you're not limited to predefined sizes of cells.

Usage

The idea behind this layout is to split UICollectionView bounds into some kind of "matrix". To do this ADMozaikCollectionViewLayout requires height for rows and width for columns in specific section.

/// Designated initializer for `ADMozaikLayout`
///
/// - Parameter delegate: delegate/datasource for the layout
public init(delegate: ADMozaikLayoutDelegate)

It requires the delegate object conforms to protocol ADMozaikLayoutDelegate. The first required method is to return the size of each item in layout:

/// Method should return `ADMozaikLayoutSize` for specific indexPath
///
/// - Parameter collectionView: collection view is using layout
/// - Parameter layout:         layout itself
/// - Parameter indexPath:      indexPath of item for the size it asks for
///
/// - Returns: `ADMozaikLayoutSize` struct object describes the size
func collectionView(_ collectionView: UICollectionView, mozaik layout: ADMozaikLayout, mozaikSizeForItemAt indexPath: IndexPath) -> ADMozaikLayoutSize

Where ADMozaikLayoutSize describes the size of each cell in terms of ADMozaikCollectionViewLayout

/**
 *  Defines the size of the layout item
 */
public struct ADMozaikLayoutSize {
  /// Columns number that item requires
  let columns: Int
  /// Rows number that item requires
  let rows: Int
}

The second method is to get the geometry information for each specific section of layout:

/// Method should return `ADMozaikLayoutSectionGeometryInfo` to describe specific section's geometry
///
/// - Parameters:
///   - collectionView: collection view is using layout
///   - layoyt:         layout itself
///   - section:        section to calculate geometry info for
///
/// - Returns: `ADMozaikLayoutSectionGeometryInfo` struct object describes the section's geometry
func collectonView(_ collectionView: UICollectionView, mozaik layoyt: ADMozaikLayout, geometryInfoFor section: ADMozaikLayoutSection) -> ADMozaikLayoutSectionGeometryInfo

Where ADMozaikLayoutSectionGeometryInfo describes the all geometry parameters of the section

/**
 *  Defines the layout's information
 */
public struct ADMozaikLayoutSectionGeometryInfo {
  /// array of `ADMozaikLayoutColumn` for the layout
  let columns: [ADMozaikLayoutColumn]

  /// height for each row in points
  let rowHeight: CGFloat

  /// minimum space between items
  let minimumInteritemSpacing: CGFloat

  /// minimum space between each row
  let minimumLineSpacing: CGFloat

  /// Insets for the section from top, left, right, bottom
  let sectionInset: UIEdgeInsets

  /// Height for header in section
  /// Width is currently limited to the collection view width
  let headerHeight: CGFloat

  /// Height for footer in section
  /// Width is currently limited to the collection view width
  let footerHeight: CGFloat
}

Content mode options

/// Method should return `ADMozaikLayoutSectionContentMode` to describe specific section's geometry
///
/// - Parameters:
///   - collectionView: collection view is using layout
///   - layout:         layout itself
///   - section:        section to return content mode for
///
/// - Returns: `ADMozaikLayoutSectionContentMode` enum describes the section's content mode and how to position cells
func collectonView(_ collectionView: UICollectionView, mozaik layout: ADMozaikLayout, contentModeFor section: ADMozaikLayoutSection) -> ADMozaikLayoutSectionContentMode

The contentMode option controls the way how the Mozaik layout is filled with items:

  1. fill - tries to fill vacant spaces with item;
  2. ordered - keeps order of the provided items, so empty space can appear in the collection view.

For the complete example please check the example project. Note that current example project is supposed to be run on iPhone 8 screen's size.

Install

CocoaPods

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

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

pod 'ADMozaicCollectionViewLayout', '~> 4.0'

Carthage

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

github "Antondomashnev/ADMozaicCollectionViewLayout" ~> 4.0

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

Migration guide

License

ADMozaicCollectionViewLayout is available under the MIT license. See LICENSE for more information.

admozaiccollectionviewlayout's People

Contributors

antondomashnev avatar cyrilchandelier avatar pawlowskialex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

admozaiccollectionviewlayout's Issues

Create ADMozaikLayout in xib or Storyboard

It would be great to have posibility to create ADMozaikLayout from xib or Storyboard.

Now, we have init?(coder aDecoder: NSCoder) but then we are not able to set up correctly rowHeight and columns.

Compilation warning on collectionView(_:layout:mozaikSizeForItemAtIndexPath:)

Since a couple versions of Xcode (probably after migration to Swift 3.0), I have this warning that I can not silent:

Instance method 'collectionView(_:layout:mozaikSizeForItemAtIndexPath:)' nearly matches optional requirement 'collectionView(_:layout:sizeForItemAt:)' of protocol 'UICollectionViewDelegateFlowLayout'

Any idea how to fix that?

Thanks,
Cyril

If you want to create cell as per you image aspect ratio

func collectonView(_ collectionView: UICollectionView, mozaik layoyt: ADMozaikLayout, geometryInfoFor section: ADMozaikLayoutSection) -> ADMozaikLayoutSectionGeometryInfo {
let W = self.view.frame.size.width/2 // - 10
let rowHeight: CGFloat = self.view.frame.size.width/12 //W //93
let columns = [ADMozaikLayoutColumn(width: W), ADMozaikLayoutColumn(width: W), ADMozaikLayoutColumn(width: W), ADMozaikLayoutColumn(width: W)]
let geometryInfo = ADMozaikLayoutSectionGeometryInfo(rowHeight: rowHeight,
columns: columns,
minimumInteritemSpacing: 1,
minimumLineSpacing: 1,
sectionInset: UIEdgeInsets(top: 5, left: 0, bottom: 5, right: 0),
headerHeight: 1, footerHeight: 1)
return geometryInfo
}

func collectionView(_ collectionView: UICollectionView, mozaik layout: ADMozaikLayout, mozaikSizeForItemAt indexPath: IndexPath) -> ADMozaikLayoutSize {
    let image = photos[indexPath.row].image
    let aspectratio = image.size.width/image.size.height
    
    if aspectratio == 1/1 {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 6)
    }
    if aspectratio == 2/3 {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 9)
    }
    if aspectratio == 3/2 {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 4)
    }
    if aspectratio == 2/1 {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 3)
    }
    if aspectratio == 1/2 {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 12)
    }
    else {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 6)
    }
}

Slow performance issues

Currently, the way of position calculation is way not optimized. I need to find a way to speed up the process, otherwise, in a big list the layout is slow

Cells are disappearing

I have implemented the layout in my app but in some cases the cells are disappearing, like in the picture below:

IMG_1241

I noticed that only bigger cells disappear. It would be great if you could take a look at this bug

use in UIViewController, but The ViewController not deinit,please help me, thanks

private lazy var collectionView : UICollectionView = {
let view = UICollectionView.init(frame: .zero, collectionViewLayout: ADMozaikLayout(delegate: self))
view.backgroundColor = UIColor.white
view.delegate = self
view.dataSource = self
view.register(OwohThemePlazaCollectionViewCell.self,
forCellWithReuseIdentifier: NSStringFromClass(OwohThemePlazaCollectionViewCell.self))
view.addRefreshEffect(headerRefreshBlock: { [weak self] in
self?.loadData()
}) { [weak self] in
self?.loadMore()
}
return view
}()

// MARK: - ADMozaikLayoutDelegate
extension OwohThemePlazaViewController : ADMozaikLayoutDelegate {
func collectonView(_ collectionView: UICollectionView,
mozaik layoyt: ADMozaikLayout,
geometryInfoFor section: ADMozaikLayoutSection) -> ADMozaikLayoutSectionGeometryInfo {
let rowHeight: CGFloat = itemSize.height
let columns = [ADMozaikLayoutColumn(width: itemSize.width),
ADMozaikLayoutColumn(width: itemSize.width),
ADMozaikLayoutColumn(width: itemSize.width)]
let geometryInfo = ADMozaikLayoutSectionGeometryInfo(rowHeight: rowHeight,
columns: columns,
minimumInteritemSpacing: itemSpacing,
minimumLineSpacing: itemSpacing,
sectionInset: .zero,
headerHeight: 0,
footerHeight: 0)
return geometryInfo
}

func collectionView(_ collectionView: UICollectionView,
                    mozaik layout: ADMozaikLayout,
                    mozaikSizeForItemAt indexPath: IndexPath) -> ADMozaikLayoutSize {
    if self.bigCellIndexs.contains(indexPath.item){
        return ADMozaikLayoutSize(numberOfColumns: 2, numberOfRows: 2)
    }
    return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 1)
}

}

how to get width dynamically ?

hi there,
Due to the device size & orientation, how can i get proper width dynamically ?
i divide column count with collection-view width size but results not as expected.

Header workaround

Great pod, thanks! Do you plan to implement headers/footers anytime soon? Do you have a workaround solution for a header until this is implemented?

I'm stuck here. Thanks!

How to add sticky header?

Hi! In default collection view layout we can use 'sectionHeadersPinToVisibleBounds'. How can I pin header in this layout?

Build error

I'm getting a build error (only in our CI tool, not in XCode):

Pods/ADMozaicCollectionViewLayout/ADMozaikCollectionViewLayout/Private/ADMozaikLayoutAttributes.swift:[102,39] 'Error' is not convertible to 'CustomStringConvertible'; did you mean to use 'as!' to force downcast? » fatalError((error as CustomStringConvertible).description)

Horizontal layout?

Hello,

I really like the layout. However, is there a way to make this layout horizontal instead of vertical?

Thank you.

My regards.

Support orientation changes

The original issue is addressed #4 .
Initial idea is to ask the user before orientation is changed for the new ADMozaikLayoutColumn, so then we can reload layout either with or without animation.

The Order of Cells changes.

I have data in a particular order and want to show three types of cell i.e Full, Half and Quarter. The collectionView works fine most of the times but sometimes the quarter cell which should be shown at last appears at some random place in collection view.

Carthage can't build library

The library needs some pods installed, but by default, it's downloaded without pods, and build crashes. If I try to install pods manually in carthage checkouts folder, it still crashes with "The sandbox is not in sync with the Podfile.lock." error.
There is no cache for swift 4 version, so, carthage doesn't use it too

Cells keep getting deallocated while scrolling

I noticed flickering in cells during scrolling. It wasn't happening while using default flow layout so I started debugging and found out that while using layout from this library, the cells are getting deallocated randomly and sometimes they just don't appear.
I placed a print statement in the deinit of my custom cell class to catch it

Crash on ADMozaikLayoutSectionMatrixError.rowOutOfBounds

`fileprivate var mosaicLayout: ADMozaikLayout {
let layout = ADMozaikLayout(delegate: self)
return layout
}
func setupCollection() {

    self.collection.collectionViewLayout.invalidateLayout()
    self.collection.setCollectionViewLayout(self.mosaicLayout, animated: true)
    
    collection.delegate = self
    collection.dataSource = self
    collection.reloadData()
    
}

extension PostGridCell: ADMozaikLayoutDelegate {

func collectionView(_ collectionView: UICollectionView, mozaik layout: ADMozaikLayout, mozaikSizeForItemAt indexPath: IndexPath) -> ADMozaikLayoutSize {
    
    
    if indexPath.item == 0 {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 1)
    }
    if indexPath.item % 8 == 0 {
        return ADMozaikLayoutSize(numberOfColumns: 2, numberOfRows: 2)
    }
    else if indexPath.item % 6 == 0 {
        return ADMozaikLayoutSize(numberOfColumns: 3, numberOfRows: 1)
    }
    else if indexPath.item % 4 == 0 {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 3)
    }
    else {
        return ADMozaikLayoutSize(numberOfColumns: 1, numberOfRows: 1)
    }
}

func collectonView(_ collectionView: UICollectionView, mozaik layoyt: ADMozaikLayout, geometryInfoFor section: ADMozaikLayoutSection) -> ADMozaikLayoutSectionGeometryInfo {
    let width = UIScreen.main.bounds.width/5
    
    let rowHeight: CGFloat = width//layoutType == .portrait ? 93 : 110
    let columns = [ADMozaikLayoutColumn(width: width), ADMozaikLayoutColumn(width: width), ADMozaikLayoutColumn(width: width), ADMozaikLayoutColumn(width: width)]
    
    let geometryInfo = ADMozaikLayoutSectionGeometryInfo(rowHeight: rowHeight, columns: columns,  minimumInteritemSpacing: 5,minimumLineSpacing: 5,sectionInset: UIEdgeInsets(top: 5, left: 0, bottom: 5, right: 0),headerHeight: 0, footerHeight: 0)
    return geometryInfo
}

}
extension PostGridCell : UICollectionViewDataSource,UICollectionViewDelegate{

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 100
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PostCell.reuseIdentifier, for: indexPath)
    cell.backgroundColor = .red
    return cell
}

}
`

This is how i configured the collectionview the library crashes on Crash on ADMozaikLayoutSectionMatrixError.rowOutOfBounds

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.