-
Notifications
You must be signed in to change notification settings - Fork 0
/
CHTCollectionViewWaterfallLayout.h
325 lines (295 loc) · 12.8 KB
/
CHTCollectionViewWaterfallLayout.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
//
// UICollectionViewWaterfallLayout.h
//
// Created by Nelson on 12/11/19.
// Copyright (c) 2012 Nelson Tai. All rights reserved.
//
#import <UIKit/UIKit.h>
/**
* Enumerated structure to define direction in which items can be rendered.
*/
typedef NS_ENUM (NSUInteger, CHTCollectionViewWaterfallLayoutItemRenderDirection) {
CHTCollectionViewWaterfallLayoutItemRenderDirectionShortestFirst,
CHTCollectionViewWaterfallLayoutItemRenderDirectionLeftToRight,
CHTCollectionViewWaterfallLayoutItemRenderDirectionRightToLeft
};
/**
* Constants that specify the types of supplementary views that can be presented using a waterfall layout.
*/
/// A supplementary view that identifies the header for a given section.
extern NSString *const CHTCollectionElementKindSectionHeader;
/// A supplementary view that identifies the footer for a given section.
extern NSString *const CHTCollectionElementKindSectionFooter;
#pragma mark - CHTCollectionViewDelegateWaterfallLayout
@class CHTCollectionViewWaterfallLayout;
/**
* The CHTCollectionViewDelegateWaterfallLayout protocol defines methods that let you coordinate with a
* CHTCollectionViewWaterfallLayout object to implement a waterfall-based layout.
* The methods of this protocol define the size of items.
*
* The waterfall layout object expects the collection view’s delegate object to adopt this protocol.
* Therefore, implement this protocol on object assigned to your collection view’s delegate property.
*/
@protocol CHTCollectionViewDelegateWaterfallLayout <UICollectionViewDelegate>
@required
/**
* Asks the delegate for the size of the specified item’s cell.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param indexPath
* The index path of the item.
*
* @return
* The original size of the specified item. Both width and height must be greater than 0.
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
@optional
/**
* Asks the delegate for the column count in a section
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The section.
*
* @return
* The original column count for that section. Must be greater than 0.
*/
- (NSInteger)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout columnCountForSection:(NSInteger)section;
/**
* Asks the delegate for the height of the header view in the specified section.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The index of the section whose header size is being requested.
*
* @return
* The height of the header. If you return 0, no header is added.
*
* @discussion
* If you do not implement this method, the waterfall layout uses the value in its headerHeight property to set the size of the header.
*
* @see
* headerHeight
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout heightForHeaderInSection:(NSInteger)section;
/**
* Asks the delegate for the height of the footer view in the specified section.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The index of the section whose header size is being requested.
*
* @return
* The height of the footer. If you return 0, no footer is added.
*
* @discussion
* If you do not implement this method, the waterfall layout uses the value in its footerHeight property to set the size of the footer.
*
* @see
* footerHeight
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout heightForFooterInSection:(NSInteger)section;
/**
* Asks the delegate for the insets in the specified section.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The index of the section whose insets are being requested.
*
* @discussion
* If you do not implement this method, the waterfall layout uses the value in its sectionInset property.
*
* @return
* The insets for the section.
*/
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
/**
* Asks the delegate for the header insets in the specified section.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The index of the section whose header insets are being requested.
*
* @discussion
* If you do not implement this method, the waterfall layout uses the value in its headerInset property.
*
* @return
* The headerInsets for the section.
*/
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForHeaderInSection:(NSInteger)section;
/**
* Asks the delegate for the footer insets in the specified section.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The index of the section whose footer insets are being requested.
*
* @discussion
* If you do not implement this method, the waterfall layout uses the value in its footerInset property.
*
* @return
* The footerInsets for the section.
*/
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForFooterInSection:(NSInteger)section;
/**
* Asks the delegate for the minimum spacing between two items in the same column
* in the specified section. If this method is not implemented, the
* minimumInteritemSpacing property is used for all sections.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The index of the section whose minimum interitem spacing is being requested.
*
* @discussion
* If you do not implement this method, the waterfall layout uses the value in its minimumInteritemSpacing property to determine the amount of space between items in the same column.
*
* @return
* The minimum interitem spacing.
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
/**
* Asks the delegate for the minimum spacing between colums in a secified section. If this method is not implemented, the
* minimumColumnSpacing property is used for all sections.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The index of the section whose minimum interitem spacing is being requested.
*
* @discussion
* If you do not implement this method, the waterfall layout uses the value in its minimumColumnSpacing property to determine the amount of space between columns in each section.
*
* @return
* The minimum spacing between each column.
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumColumnSpacingForSectionAtIndex:(NSInteger)section;
@end
#pragma mark - CHTCollectionViewWaterfallLayout
/**
* The CHTCollectionViewWaterfallLayout class is a concrete layout object that organizes items into waterfall-based grids
* with optional header and footer views for each section.
*
* A waterfall layout works with the collection view’s delegate object to determine the size of items, headers, and footers
* in each section. That delegate object must conform to the `CHTCollectionViewDelegateWaterfallLayout` protocol.
*
* Each section in a waterfall layout can have its own custom header and footer. To configure the header or footer for a view,
* you must configure the height of the header or footer to be non zero. You can do this by implementing the appropriate delegate
* methods or by assigning appropriate values to the `headerHeight` and `footerHeight` properties.
* If the header or footer height is 0, the corresponding view is not added to the collection view.
*
* @note CHTCollectionViewWaterfallLayout doesn't support decoration view, and it supports vertical scrolling direction only.
*/
@interface CHTCollectionViewWaterfallLayout : UICollectionViewLayout
/**
* @brief How many columns for this layout.
* @discussion Default: 2
*/
@property (nonatomic, assign) NSInteger columnCount;
/**
* @brief The minimum spacing to use between successive columns.
* @discussion Default: 10.0
*/
@property (nonatomic, assign) CGFloat minimumColumnSpacing;
/**
* @brief The minimum spacing to use between items in the same column.
* @discussion Default: 10.0
* @note This spacing is not applied to the space between header and columns or between columns and footer.
*/
@property (nonatomic, assign) CGFloat minimumInteritemSpacing;
/**
* @brief Height for section header
* @discussion
* If your collectionView's delegate doesn't implement `collectionView:layout:heightForHeaderInSection:`,
* then this value will be used.
*
* Default: 0
*/
@property (nonatomic, assign) CGFloat headerHeight;
/**
* @brief Height for section footer
* @discussion
* If your collectionView's delegate doesn't implement `collectionView:layout:heightForFooterInSection:`,
* then this value will be used.
*
* Default: 0
*/
@property (nonatomic, assign) CGFloat footerHeight;
/**
* @brief The margins that are used to lay out the header for each section.
* @discussion
* These insets are applied to the headers in each section.
* They represent the distance between the top of the collection view and the top of the content items
* They also indicate the spacing on either side of the header. They do not affect the size of the headers or footers themselves.
*
* Default: UIEdgeInsetsZero
*/
@property (nonatomic, assign) UIEdgeInsets headerInset;
/**
* @brief The margins that are used to lay out the footer for each section.
* @discussion
* These insets are applied to the footers in each section.
* They represent the distance between the top of the collection view and the top of the content items
* They also indicate the spacing on either side of the footer. They do not affect the size of the headers or footers themselves.
*
* Default: UIEdgeInsetsZero
*/
@property (nonatomic, assign) UIEdgeInsets footerInset;
/**
* @brief The margins that are used to lay out content in each section.
* @discussion
* Section insets are margins applied only to the items in the section.
* They represent the distance between the header view and the columns and between the columns and the footer view.
* They also indicate the spacing on either side of columns. They do not affect the size of the headers or footers themselves.
*
* Default: UIEdgeInsetsZero
*/
@property (nonatomic, assign) UIEdgeInsets sectionInset;
/**
* @brief The direction in which items will be rendered in subsequent rows.
* @discussion
* The direction in which each item is rendered. This could be left to right (CHTCollectionViewWaterfallLayoutItemRenderDirectionLeftToRight), right to left (CHTCollectionViewWaterfallLayoutItemRenderDirectionRightToLeft), or shortest column fills first (CHTCollectionViewWaterfallLayoutItemRenderDirectionShortestFirst).
*
* Default: CHTCollectionViewWaterfallLayoutItemRenderDirectionShortestFirst
*/
@property (nonatomic, assign) CHTCollectionViewWaterfallLayoutItemRenderDirection itemRenderDirection;
/**
* @brief The minimum height of the collection view's content.
* @discussion
* The minimum height of the collection view's content. This could be used to allow hidden headers with no content.
*
* Default: 0.f
*/
@property (nonatomic, assign) CGFloat minimumContentHeight;
/**
* @brief The calculated width of an item in the specified section.
* @discussion
* The width of an item is calculated based on number of columns, the collection view width, and the horizontal insets for that section.
*/
- (CGFloat)itemWidthInSectionAtIndex:(NSInteger)section;
@end