Skip to content

Commit 11c8c7c

Browse files
author
Igor Vedeneev
committed
add collectionview size for cell size calculation
1 parent 0c39548 commit 11c8c7c

9 files changed

Lines changed: 69 additions & 38 deletions

File tree

CollectionKit.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
D638A9081F9D25EE00B858E9 /* CollectionItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69EEF7C1F689911002B29E4 /* CollectionItem.swift */; };
2727
D638A9091F9D25EE00B858E9 /* CollectionSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69EEF801F690F70002B29E4 /* CollectionSection.swift */; };
2828
D638A90A1F9D25EE00B858E9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CBBEB01F82F048007CD4A7 /* Helpers.swift */; };
29+
D66BFA951FD3648E0095EC38 /* Header.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66BFA941FD3648E0095EC38 /* Header.swift */; };
2930
D681B53D1FC4D0E10015A2CF /* CollectionUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = D681B53C1FC4D0E10015A2CF /* CollectionUpdater.swift */; };
3031
D69EEF6E1F6894F5002B29E4 /* CollectionKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69EEF6D1F6894F5002B29E4 /* CollectionKitTests.swift */; };
3132
D6EF701C1FAA7CFD00164BA9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D6EF701E1FAA7CFD00164BA9 /* Localizable.strings */; };
@@ -77,6 +78,7 @@
7778
D638A8FD1F9D25AF00B858E9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
7879
D638A9001F9D25AF00B858E9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
7980
D638A9021F9D25AF00B858E9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
81+
D66BFA941FD3648E0095EC38 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = "<group>"; };
8082
D681B53C1FC4D0E10015A2CF /* CollectionUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionUpdater.swift; sourceTree = "<group>"; };
8183
D69EEF581F6894F5002B29E4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = ../CollectionKit/AppDelegate.swift; sourceTree = "<group>"; };
8284
D69EEF5A1F6894F5002B29E4 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = ../CollectionKit/ViewController.swift; sourceTree = "<group>"; };
@@ -171,6 +173,7 @@
171173
D638A9021F9D25AF00B858E9 /* Info.plist */,
172174
D619850F1FCB201E00D6BCB1 /* CellFromXIB.swift */,
173175
D61985111FCB235C00D6BCB1 /* CellFromXIB.xib */,
176+
D66BFA941FD3648E0095EC38 /* Header.swift */,
174177
);
175178
path = Examples;
176179
sourceTree = "<group>";
@@ -396,6 +399,7 @@
396399
isa = PBXSourcesBuildPhase;
397400
buildActionMask = 2147483647;
398401
files = (
402+
D66BFA951FD3648E0095EC38 /* Header.swift in Sources */,
399403
D6077EF91F9FF38600DD8CA6 /* ViewController.swift in Sources */,
400404
D6077EFA1F9FF38600DD8CA6 /* AppDelegate.swift in Sources */,
401405
D6077EFB1F9FF38600DD8CA6 /* CollectionCell.swift in Sources */,

CollectionKit/CollectionCell.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class CollectionCell: UICollectionViewCell {
3434
}
3535

3636
extension CollectionCell : ConfigurableCollectionItem {
37-
static func estimatedSize(item: String?) -> CGSize {
38-
return CGSize(width: UIScreen.main.bounds.width, height: 50)
37+
static func estimatedSize(item: String?, collectionViewSize: CGSize) -> CGSize {
38+
return CGSize(width: collectionViewSize.width, height: 50)
3939
}
4040

4141
func configure(item: String) {

CollectionKit/CollectionDirector.swift

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import UIKit
2727
open class CollectionDirector: NSObject {
2828
public var sections = [AbstractCollectionSection]()
2929
open var shouldUseAutomaticCellRegistration: Bool = false
30-
///Adjust z position for headers/footers @ iOS11
30+
///Adjust z position for headers/footers to prevent scroll indicator hiding at iOS11
3131
open var shouldAdjustSupplementaryViewLayerZPosition: Bool = true
3232
private weak var collectionView: UICollectionView!
3333
private var reuseIdentifiers: Set<String> = []
@@ -77,12 +77,6 @@ open class CollectionDirector: NSObject {
7777

7878
//todo: add/remove array of sections
7979

80-
public func performWithoutReloading(changes: (() -> Void)) {
81-
disableUpdates = true
82-
changes()
83-
disableUpdates = false
84-
}
85-
8680
public func reload() {
8781
collectionView.reloadData()
8882
}
@@ -204,7 +198,7 @@ extension CollectionDirector : UICollectionViewDelegateFlowLayout {
204198

205199
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
206200
let item = sections[indexPath.section].item(for: indexPath.row)
207-
return item.estimatedSize
201+
return item.estimatedSize(collectionViewSize: collectionView.bounds.size)
208202
}
209203

210204
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
@@ -213,13 +207,13 @@ extension CollectionDirector : UICollectionViewDelegateFlowLayout {
213207

214208
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
215209
let section_ = sections[section]
216-
let value = section_.headerItem?.estimatedSize ?? .zero
210+
let value = section_.headerItem?.estimatedSize(collectionViewSize: collectionView.bounds.size) ?? .zero
217211
return value
218212
}
219213

220214
open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
221215
let section_ = sections[section]
222-
let value = section_.footerItem?.estimatedSize ?? .zero
216+
let value = section_.footerItem?.estimatedSize(collectionViewSize: collectionView.bounds.size) ?? .zero
223217
return value
224218
}
225219

CollectionKit/CollectionItem.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@ open class CollectionItem<CellType: ConfigurableCollectionItem>: AbstractCollect
1818
open var onUnighlight: ((_ indexPath: IndexPath) -> Void)?
1919
open var shouldHighlight: Bool?
2020

21-
open var estimatedSize: CGSize { return CellType.estimatedSize(item: self.item) }
2221
open var item: CellType.T
2322
open var reuseIdentifier: String { return CellType.reuseIdentifier }
23+
2424
public let identifier: String = UUID().uuidString
2525

26+
public func estimatedSize(collectionViewSize: CGSize) -> CGSize {
27+
return CellType.estimatedSize(item: self.item, collectionViewSize: collectionViewSize)
28+
}
29+
2630
public var cellType: AnyClass {
2731
return CellType.self
2832
}

CollectionKit/Helpers.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ extension Array {
123123
//MARK:- ConfigurableCollectionItem
124124
public protocol ConfigurableCollectionItem : Reusable {
125125
associatedtype T
126-
static func estimatedSize(item: T?) -> CGSize
126+
static func estimatedSize(item: T?, collectionViewSize: CGSize) -> CGSize
127127
func configure(item: T)
128128
}
129129

@@ -143,8 +143,9 @@ public protocol ActionableCollectionItem {
143143
//MARK:- AbstractCollectionItem
144144
public protocol AbstractCollectionItem : ActionableCollectionItem {
145145
var reuseIdentifier: String { get }
146-
var estimatedSize: CGSize { get }
146+
// var estimatedSize: CGSize { get }
147147
var identifier: String { get }
148148
var cellType: AnyClass { get }
149149
func configure(_: UICollectionReusableView)
150+
func estimatedSize(collectionViewSize: CGSize) -> CGSize
150151
}

CollectionKit/ViewController.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ class ViewController: UIViewController {
1818
override func viewDidLoad() {
1919
super.viewDidLoad()
2020
if #available(iOS 11.0, *) {
21-
// navigationController?.navigationBar.prefersLargeTitles = true
22-
} else {
23-
// Fallback on earlier versions
21+
navigationController?.navigationBar.prefersLargeTitles = true
2422
}
2523

2624
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: UICollectionViewFlowLayout())
@@ -30,12 +28,14 @@ class ViewController: UIViewController {
3028
collectionView.alwaysBounceVertical = true
3129
director = CollectionDirector(colletionView: collectionView)
3230
director.shouldUseAutomaticCellRegistration = true
31+
collectionView.register(Header.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: Header.reuseIdentifier)
3332
// collectionView.registerClass(CollectionCell.self)
3433
// collectionView.registerNib(CellFromXIB.self)
3534
section = CollectionSection()
3635
section.minimumInterItemSpacing = 0.5
37-
section.insetForSection = UIEdgeInsetsMake(20, 0, 20, 0)
36+
// section.insetForSection = UIEdgeInsetsMake(20, 0, 20, 0)
3837
section.lineSpacing = 2
38+
section.headerItem = CollectionItem<Header>(item: "title")
3939
for _ in 0..<3 {
4040
let row = CollectionItem<CollectionCell>(item: "text")
4141
.onSelect({ (_) in

Examples/CellFromXIB.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ final class CellFromXIB : UICollectionViewCell {
1414
}
1515

1616
extension CellFromXIB : ConfigurableCollectionItem {
17-
static func estimatedSize(item: String?) -> CGSize {
18-
return CGSize(width: UIScreen.main.bounds.width - 40, height: 60)
17+
static func estimatedSize(item: String?, collectionViewSize: CGSize) -> CGSize {
18+
return CGSize(width: collectionViewSize.width - 40, height: 60)
1919
}
2020

2121
func configure(item: String) {

Examples/Header.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// Header.swift
3+
// Examples
4+
//
5+
// Created by Igor Vedeneev on 03.12.17.
6+
// Copyright © 2017 Igor Vedeneev. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import CollectionKit
11+
12+
final class Header: UICollectionReusableView {
13+
let titleLabel = UILabel()
14+
15+
override init(frame: CGRect) {
16+
super.init(frame: frame)
17+
titleLabel.font = UIFont.systemFont(ofSize: 12, weight: .light)
18+
titleLabel.frame = CGRect(x: 20, y: 20, width: 100, height: 13)
19+
addSubview(titleLabel)
20+
}
21+
22+
required init?(coder aDecoder: NSCoder) {
23+
fatalError("init(coder:) has not been implemented")
24+
}
25+
}
26+
27+
extension Header : ConfigurableCollectionItem {
28+
func configure(item: String) {
29+
titleLabel.text = item.uppercased()
30+
}
31+
32+
static func estimatedSize(item: String?, collectionViewSize: CGSize) -> CGSize {
33+
return CGSize(width: collectionViewSize.width, height: 48)
34+
}
35+
}

README.md

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ Framework to manage complex `UICollectionView` in declarative way and very few l
77
- [x] Type-safe generic cells
88
- [x] No need to implement `UICollectionViewDataSource` and `UICollectionViewDelegate`
99
- [x] Easy way to map your models into cells
10-
- [x] Updating without `performBatchUpdates` or whatever
10+
- [x] Convinient updations
1111
- [x] Supports cells from code and xibs and storyboard
1212
- [x] Supports custom section imlementations
1313
- [x] Register cells and reusable views automatically
14-
- [x] Automatic cells and reusable views registration (if needed)
14+
- [x] Fix scroll indicator clipping at iOS11 (https://stackoverflow.com/questions/46747960/ios11-uicollectionsectionheader-clipping-scroll-indicator)
1515

1616
# Getting Started
1717

@@ -43,8 +43,8 @@ director += section
4343
Cell must implement `ConfigurableCollectionCell` protocol. You need to specify cell size and configure methods:
4444
```swift
4545
extension CollectionCell : ConfigurableCollectionItem {
46-
static func estimatedSize(item: String?) -> CGSize {
47-
return CGSize(width: UIScreen.main.bounds.width, height: 50)
46+
static func estimatedSize(item: String, collectionViewSize: CGSize) -> CGSize {
47+
return CGSize(width: collectionViewSize.width, height: 50)
4848
}
4949

5050
func configure(item: String) {
@@ -74,20 +74,13 @@ section.lineSpacing = 2
7474
```
7575

7676
## Updating
77-
You can update collection view only by operating with section and item objects without any `performBatchUpdates`:
77+
You can update collection view only by operating with section and item objects without any `IndexPath` mess: put usual operations in `performUpdates` block
7878
```swift
79-
// insert item at specific position
80-
let row = CollectionItem<CollectionCell>(item: "hello")
81-
section.insert(item: row, at: 0)
82-
83-
//append item to bottom of section
84-
section.append(item: row)
85-
86-
//remove item at specific position
87-
section.remove(at: 0)
88-
89-
//reload cell
90-
row.reload(with: "reloaded")
79+
self.director.performUpdates { [unowned self] in
80+
self.section.append(item: row)
81+
self.section.insert(item: row, at: 0)
82+
self.section.remove(item: item)
83+
}
9184
```
9285

9386
## Custom sections

0 commit comments

Comments
 (0)