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

https://github.com/hyun99999/pinteresttutorial-ios

๐ŸฅบPinterest Layout Tutorial
https://github.com/hyun99999/pinteresttutorial-ios

Last synced: about 2 months ago
JSON representation

๐ŸฅบPinterest Layout Tutorial

Awesome Lists containing this project

README

        

# PinterestTutorial-iOS
๐ŸฅบPinterest Layout Tutorial

์ด๋ฏธ์ง€ ํฌ๊ธฐ์— ๋”ฐ๋ผ์„œ ๋™์ ์œผ๋กœ ์…€์˜ ๋ ˆ์ด์•„์›ƒ์„ ์„ค์ •ํ•˜๋Š” ํ•€ํ„ฐ๋ ˆ์ŠคํŠธ ๋ ˆ์ด์•„์›ƒ ๊ตฌํ˜„ํ•ด ๋ณด์•˜๋‹ค.

### ์™„์„ฑ

### ์ฝ”๋“œ

- UICollectionViewDelegateFlowLayout ์˜ ์„œ๋ธŒํด๋ž˜์Šค์ธ PinterestLayout ์ƒ์„ฑ.
```swift
// PinterestLayout ์—์„œ ๊ฐ ์ด๋ฏธ์ง€ ๋†’์ด๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋„๋ก Delegate ์ƒ์„ฑ.
protocol PinterestLayoutDelegate: AnyObject {
func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat
}

class PinterestLayout: UICollectionViewFlowLayout {

// delegate๋กœ ViewController ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
weak var delegate: PinterestLayoutDelegate?

private var contentHeight: CGFloat = 0

private var contentWidth: CGFloat {
guard let collectionView = collectionView else {
return 0
}
let insets = collectionView.contentInset
return collectionView.bounds.width - (insets.left + insets.right)
}

// 1. ์ฝœ๋ ‰์…˜ ๋ทฐ์˜ ์ฝ˜ํ…์ธ  ์‚ฌ์ด์ฆˆ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
override var collectionViewContentSize: CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}

// ๋‹ค์‹œ ๋ ˆ์ด์•„์›ƒ์„ ๊ณ„์‚ฐํ•  ํ•„์š”๊ฐ€ ์—†๋„๋ก ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
private var cache: [UICollectionViewLayoutAttributes] = []

// 2. ์ฝœ๋ ‰์…˜ ๋ทฐ๊ฐ€ ์ฒ˜์Œ ์ดˆ๊ธฐํ™”๋˜๊ฑฐ๋‚˜ ๋ทฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋–„ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ์—์„œ ๋ ˆ์ด์•„์›ƒ์„
// ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌํ•˜๊ณ , ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ํšจ์œจ์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
override func prepare() {
guard let collectionView = collectionView, cache.isEmpty else { return }

let numberOfColumns: Int = 2 // ํ•œ ํ–‰์˜ ์•„์ดํ…œ ๊ฐฏ์ˆ˜
let cellPadding: CGFloat = 5
let cellWidth: CGFloat = contentWidth / CGFloat(numberOfColumns)

let xOffSet: [CGFloat] = [0, cellWidth] // cell ์˜ x ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฐ์—ด
var yOffSet: [CGFloat] = .init(repeating: 0, count: numberOfColumns) // // cell ์˜ y ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฐ์—ด

var column: Int = 0 // ํ˜„์žฌ ํ–‰์˜ ์œ„์น˜

for item in 0.. yOffSet[1] ? 1 : 0
}
}

// 3. ๋ชจ๋“  ์…€๊ณผ ๋ณด์ถฉ ๋ทฐ์˜ ๋ ˆ์ด์•„์›ƒ ์ •๋ณด๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. ํ™”๋ฉด ํ‘œ์‹œ ์˜์—ญ ๊ธฐ๋ฐ˜(Rect)์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
override func layoutAttributesForElements(in rect: CGRect)
-> [UICollectionViewLayoutAttributes]? {
var visibleLayoutAttributes: [UICollectionViewLayoutAttributes] = []

for attributes in cache {
if attributes.frame.intersects(rect) { // ์…€ frame ๊ณผ ์š”์ฒญ Rect ๊ฐ€ ๊ต์ฐจํ•œ๋‹ค๋ฉด, ๋ฆฌํ„ด ๊ฐ’์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
visibleLayoutAttributes.append(attributes)
}
}

return visibleLayoutAttributes
}

// 4. ๋ชจ๋“  ์…€์˜ ๋ ˆ์ด์•„์›ƒ ์ •๋ณด๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. IndexPath ๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜ฌ ๋•Œ ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
override func layoutAttributesForItem(at indexPath: IndexPath)
-> UICollectionViewLayoutAttributes? {
return cache[indexPath.item]
}
}
```
- MainVC ์—์„œ PinterestLayoutDelegate ๋ฅผ ์ฑ„ํƒ.

```swift
// MARK: - UICollectionViewDelegateFlowLayout
extension MainVC: PinterestLayoutDelegate {
func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat {
let cellWidth: CGFloat = (view.bounds.width - 4) / 2 // ์…€ ๊ฐ€๋กœ ํฌ๊ธฐ
let imageHeight = imageList[indexPath.item].image.size.height
let imageWidth = imageList[indexPath.item].image.size.width
// ์ด๋ฏธ์ง€ ๋น„์œจ
let imageRatio = imageHeight/imageWidth


return imageRatio * cellWidth
}
}
```

### ์ถœ์ฒ˜
์ถœ์ฒ˜ใ…ฃ[Swift. UICollectionView Pinterest ๋ ˆ์ด์•„์›ƒ](https://devmjun.github.io/archive/CollectionView-Pinterest)