Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/iwheelbuy/SquareMosaicLayout

An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations :large_orange_diamond:
https://github.com/iwheelbuy/SquareMosaicLayout

ios swift uicollectionview uicollectionviewflowlayout uicollectionviewlayout uikit uitableview

Last synced: 5 days ago
JSON representation

An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations :large_orange_diamond:

Awesome Lists containing this project

README

        

# SquareMosaicLayout

[![Version](https://img.shields.io/cocoapods/v/SquareMosaicLayout.svg?style=flat)](https://cocoapods.org/pods/SquareMosaicLayout)
[![License](https://img.shields.io/cocoapods/l/SquareMosaicLayout.svg?style=flat)](https://raw.githubusercontent.com/iwheelbuy/SquareMosaicLayout/master/LICENSE)
![Platform](https://img.shields.io/cocoapods/p/SquareMosaicLayout.svg?style=flat)

An extandable mosaic UICollectionViewLayout with a focus on extremely flexible customizations.

## Note

This layout is not of [waterfall](https://www.raywenderlich.com/107439/uicollectionview-custom-layout-tutorial-pinterest) type. It was designed for layouts where we can predict the size of rectangular box which contains the number of full cells. Check out how to copy [TRMosaicLayout](https://github.com/iwheelbuy/SquareMosaicLayout#example---copying-trmosaiclayout) or [FMMosaicLayout](https://github.com/iwheelbuy/SquareMosaicLayout#example---copying-fmmosaiclayout) using __SquareMosaicLayout__

## Visual

| Example | Layout | Pattern | Blocks |
|:-:|:-:|:-:|:-:|
| ![image1](https://github.com/iwheelbuy/SquareMosaicLayout/blob/master/Example/SquareMosaicLayout/ezgif.com-optimize.gif) | ![image2](https://github.com/iwheelbuy/SquareMosaicLayout/blob/master/Example/SquareMosaicLayout/rsz_1.png) | ![image3](https://github.com/iwheelbuy/SquareMosaicLayout/blob/master/Example/SquareMosaicLayout/rsz_12.png) | ![image4](https://github.com/iwheelbuy/SquareMosaicLayout/blob/master/Example/SquareMosaicLayout/rsz_3.png) |
| Build and run an example project to see how it really works | Let's imagine that we want a UICollectionView with some mosaic layout that looks like this | The red part of frames repeats while scrolling. So we should do only the red __pattern__ and then repeat it | The __pattern__ is split it into smaller __blocks__ that can be reused for some other layout or __pattern__ |

## Installation

SquareMosaicLayout is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:

```ruby
pod 'SquareMosaicLayout', '4.1.2'
```

## Capabilities

- [x] Layout can be vertical or horizontal.
- [x] Each section can have its own __pattern__ of frames.
- [x] Each section can have its own header frame (optional).
- [x] Each section can have its own footer frame (optional).
- [x] Each section can have its own background (optional).
- [x] Space between sections can be changed (optional).
- [x] Space between, before and after __blocks__ in __pattern__ can be changed (optional).
- [x] Each section can have one repeated __block__.

## Author

iwheelbuy, [email protected]

## License

SquareMosaicLayout is available under the MIT license. See the [LICENSE](https://raw.githubusercontent.com/iwheelbuy/SquareMosaicLayout/master/LICENSE) file for more info.

## Example - copying [TRMosaicLayout](https://github.com/vinnyoodles/TRMosaicLayout)

```swift
final class TRMosaicLayoutCopy: SquareMosaicLayout, SquareMosaicDataSource {

convenience init() {
self.init(direction: SquareMosaicDirection.vertical)
self.dataSource = self
}

func layoutPattern(for section: Int) -> SquareMosaicPattern {
return TRMosaicLayoutCopyPattern()
}
}

class TRMosaicLayoutCopyPattern: SquareMosaicPattern {

func patternBlocks() -> [SquareMosaicBlock] {
return [
TRMosaicLayoutCopyBlock1(),
TRMosaicLayoutCopyBlock2()
]
}
}

public class TRMosaicLayoutCopyBlock1: SquareMosaicBlock {

public func blockFrames() -> Int {
return 3
}

public func blockFrames(origin: CGFloat, side: CGFloat) -> [CGRect] {
let minWidth = side / 3.0
let maxWidth = side - minWidth
let minHeight = minWidth * 1.5
let maxHeight = minHeight + minHeight
var frames = [CGRect]()
frames.append(CGRect(x: 0, y: origin, width: maxWidth, height: maxHeight))
frames.append(CGRect(x: maxWidth, y: origin, width: minWidth, height: minHeight))
frames.append(CGRect(x: maxWidth, y: origin + minHeight, width: minWidth, height: minHeight))
return frames
}
}

public class TRMosaicLayoutCopyBlock2: SquareMosaicBlock {

public func blockFrames() -> Int {
return 3
}

public func blockFrames(origin: CGFloat, side: CGFloat) -> [CGRect] {
let minWidth = side / 3.0
let maxWidth = side - minWidth
let minHeight = minWidth * 1.5
let maxHeight = minHeight + minHeight
var frames = [CGRect]()
frames.append(CGRect(x: 0, y: origin, width: minWidth, height: minHeight))
frames.append(CGRect(x: 0, y: origin + minHeight, width: minWidth, height: minHeight))
frames.append(CGRect(x: minWidth, y: origin, width: maxWidth, height: maxHeight))
return frames
}
}
```

## Example - copying [FMMosaicLayout](https://github.com/fmitech/FMMosaicLayout)

```swift
final class FMMosaicLayoutCopy: SquareMosaicLayout, SquareMosaicDataSource {

convenience init() {
self.init(direction: SquareMosaicDirection.vertical)
self.dataSource = self
}

func layoutPattern(for section: Int) -> SquareMosaicPattern {
return FMMosaicLayoutCopyPattern()
}
}

class FMMosaicLayoutCopyPattern: SquareMosaicPattern {

func patternBlocks() -> [SquareMosaicBlock] {
return [
FMMosaicLayoutCopyBlock1(),
FMMosaicLayoutCopyBlock2(),
FMMosaicLayoutCopyBlock3(),
FMMosaicLayoutCopyBlock2(),
FMMosaicLayoutCopyBlock2()
]
}
}

public class FMMosaicLayoutCopyBlock1: SquareMosaicBlock {

public func blockFrames() -> Int {
return 5
}

public func blockFrames(origin: CGFloat, side: CGFloat) -> [CGRect] {
let min = side / 4.0
let max = side - min - min
var frames = [CGRect]()
frames.append(CGRect(x: 0, y: origin, width: max, height: max))
frames.append(CGRect(x: max, y: origin, width: min, height: min))
frames.append(CGRect(x: max, y: origin + min, width: min, height: min))
frames.append(CGRect(x: max + min, y: origin, width: min, height: min))
frames.append(CGRect(x: max + min, y: origin + min, width: min, height: min))
return frames
}
}

public class FMMosaicLayoutCopyBlock2: SquareMosaicBlock {

public func blockFrames() -> Int {
return 4
}

public func blockFrames(origin: CGFloat, side: CGFloat) -> [CGRect] {
let min = side / 4.0
var frames = [CGRect]()
frames.append(CGRect(x: 0, y: origin, width: min, height: min))
frames.append(CGRect(x: min, y: origin, width: min, height: min))
frames.append(CGRect(x: min * 2, y: origin, width: min, height: min))
frames.append(CGRect(x: min * 3, y: origin, width: min, height: min))
return frames
}
}

public class FMMosaicLayoutCopyBlock3: SquareMosaicBlock {

public func blockFrames() -> Int {
return 5
}

public func blockFrames(origin: CGFloat, side: CGFloat) -> [CGRect] {
let min = side / 4.0
let max = side - min - min
var frames = [CGRect]()
frames.append(CGRect(x: 0, y: origin, width: min, height: min))
frames.append(CGRect(x: 0, y: origin + min, width: min, height: min))
frames.append(CGRect(x: min, y: origin, width: min, height: min))
frames.append(CGRect(x: min, y: origin + min, width: min, height: min))
frames.append(CGRect(x: max, y: origin, width: max, height: max))
return frames
}
}
```