Collection view layout
-
Upload
ciklum -
Category
Technology
-
view
388 -
download
3
Transcript of Collection view layout
![Page 1: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/1.jpg)
Collection view custom
layoutWaterfall layout case study
iOS Practice Leaders
Anatoly Tukhtarov
![Page 2: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/2.jpg)
Introduction
UICollectionView is available since iOS 6
Allows present collections of data with custom
layout
Still in development
![Page 3: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/3.jpg)
Agenda
• UICollectionView and its views
• UICollectionViewLayout and its friends
• Waterfall collection view layout
![Page 4: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/4.jpg)
UICollectionView views
Managed by collection view’s data source (i.e. represent
some data)
• Cells — UICollectionViewCell
• Supplementary views (section’s or collection view’s headers, footers, etc.) —
UICollectionReusableView
Managed by collection view’s layout
• Decoration views (items separators, shadows, borders, etc.) —
UICollectionReusableView
Only cells are selectable
![Page 5: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/5.jpg)
How does collection view
know how to place its
views?UICollectionViewLayout
![Page 6: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/6.jpg)
UICollectionViewLayoutA kind of data source to provide visual information,
not data
Responsible for locations and sizes of all the cells,
supplementary and decoration views
Does not apply data to views
![Page 7: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/7.jpg)
UICollectionViewLayoutClasses
UICollectionViewLayoutAttributes
• view’s layout attributes like frame, alpha,
transform, etc.
• created and configured by layout
• must adopt NSCopying protocol
• must override equality methods
(-hash, -isEqual:)
• applied by collection view
![Page 8: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/8.jpg)
UICollectionViewLayoutClasses
UICollectionViewLayoutInvalidationContext
• available since iOS 7
• declares which parts of layout need to be updated
on layout invalidation
• capital update for iOS 8
![Page 9: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/9.jpg)
Waterfall layoutDocuments list application
![Page 10: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/10.jpg)
Documents application
• Landscape and portrait items A4 scale
• Multiple waterfall columns for iPad and iPhone
• Number of columns must be changed on device
rotation
• Drag and drop items like on home screen
• Autoscroll while dragging
v 0.1
Source code: https://github.com/swordfishyou/documents-app
![Page 11: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/11.jpg)
Designing layout
• Number of columns in section
• Column width
• Cell size
• Cell frame
• Intercolumn and interline
spacings, etc.
• Cache all the possible values
layout delegate
data source
layout
![Page 12: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/12.jpg)
Building layout- (void)buildLayout {
if (self.isPreparingLayout) {
return;
}
self.preparingLayout = YES;
/// Calculate items sizes and columns metrics
if (!self.isLayoutDataValid) {
[self buildLayoutFromDataSource];
self.layoutDataValid = YES;
}
self.layoutSize = CGSizeZero;
[self.layoutAttributes removeAllObjects];
/// Calculate (reuse) layout attributes
[self calculateLayoutAttributes];
self.preparingLayout = NO;
}
![Page 13: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/13.jpg)
Documents application
• Landscape and portrait items A4 scale
• Multiple waterfall columns for iPad and iPhone
• Number of columns must be changed on device
rotation
• Drag and drop items like on home screen
• Autoscroll while dragging
v 0.1
![Page 14: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/14.jpg)
Cell size (self-sizing cells)
- (CGSize)collectionView:(UICollectionView *)collectionView
sizeFittingSize:(CGSize)fittingSize
forItemAtIndexPath:(NSIndexPath *)indexPath {
FLSCollectionViewCell *cell = [self collectionView:collectionView
cellForItemAtIndexPath:indexPath];
CGRect frame = cell.frame;
frame.size = fittingSize;
cell.frame = frame;
CGSize size;
[cell layoutIfNeeded];
size = [cell.contentView
systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
[cell removeFromSuperview];
return size;
}
Auto layouts case
![Page 15: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/15.jpg)
Documents application
• Landscape and portrait items A4 scale
• Multiple waterfall columns for iPad and iPhone
• Number of columns must be changed on device
rotation
• Drag and drop items like on home screen
• Autoscroll while dragging
v 0.1
![Page 16: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/16.jpg)
Layout metrics
• Items’ sizes and attributes by index path
• Column metrics by section
• index
• section
• size
• items’ indexes in column
![Page 17: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/17.jpg)
Cell frame- (CGRect)itemFrameAtIndexPath:(NSIndexPath *)indexPath {
CGRect frame;
frame.size = ...; /// use cached value
CGFloat topOffset = 0.0;
for (NSInteger section = 0; section < indexPath.section; ++section) {
/// Shift vertically by sections above
}
NSInteger numberOfColumnsInSection = ...;
NSInteger itemColumn = indexPath.item % numberOfColumnsInSection;
FLSColumnLayoutMetrics *columnMetrics = ...;
for (NSInteger item = 0; item < indexPath.item; ++item) {
if ([columnMetrics.itemIndexes containsIndex:item]) {
/// Shift vertically by items in column
}
}
frame.origin.y = topOffset;
CGFloat leftOffset = itemColumn * self.minimumItercolumnSpacing;
for (NSInteger column = 0; column < itemColumn; ++column) {
/// Shift horizontally by columns left
}
/// Centre cell in item’s column
return frame;
}
![Page 18: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/18.jpg)
Documents application
• Landscape and portrait items A4 scale
• Multiple waterfall columns for iPad and iPhone
• Number of columns must be changed on device
rotation
• Drag and drop items like on home screen
• Autoscroll while dragging
v 0.1
![Page 19: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/19.jpg)
Layout invalidation@interface FLSCollectionViewLayoutInvalidationContext :
UICollectionViewLayoutInvalidationContext
@property (nonatomic, assign) BOOL invalidateLayoutMetrics;
@end
+ (Class)invalidationContextClass;
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;
- (UICollectionViewLayoutInvalidationContext *)
invalidationContextForBoundsChange:(CGRect)newBounds;
- (void)invalidateLayoutWithContext:
(FLSCollectionViewLayoutInvalidationContext *)context;
![Page 20: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/20.jpg)
Documents application
• Landscape and portrait items A4 scale
• Multiple waterfall columns for iPad and iPhone
• Number of columns must be changed on device
rotation
• Drag and drop items like on home screen
• Autoscroll while dragging
v 0.1
![Page 21: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/21.jpg)
Drag and drop
• Consider to use gestures controller or state
machine
• Layout is responsible for changing frame of a
dragging item
• Data source is responsible for handling motion
actions (like reorder array, etc.)
General ideas
![Page 22: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/22.jpg)
Drag and drop
- (void)beginDraggingItemAtIndexPath:(NSIndexPath *)indexPath {
/// Snapshot cell and index path
self.draggingIndexPath = indexPath;
UICollectionViewCell *cell = ...;
UIView *snapshot = [cell snapshotViewAfterScreenUpdates:NO];
self.draggingView = snapshot;
[self.collectionView addSubview:self.draggingView];
/// Calculate drag bounds if needed
[UIView animateWithDuration:animationDuration
animations:^{
/// Indicate dragging item with animation
} completion:^(BOOL finished) {
/// Invalidate layout
}];
}
Begin dragging
![Page 23: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/23.jpg)
Drag and drop
- (void)handlePanGesture:(UIPanGestureRecognizer *)gesture {
switch (gesture.state) {
case UIGestureRecognizerStateChanged:{
[self scheduleDraggingHoldTimer];
/// Calculate new centre of the dragging view
CGPoint translation = [gesture translationInView:self.collectionView];
CGPoint diff = ...;
self.lastTranslation = translation;
CGPoint center = ...;
[self constrainPointToDragBounds:¢er];
self.draggingView.center = center;
/// Trigger autoscroll
break;
}
case UIGestureRecognizerStateEnded:
/// Invalidate timers
break;
}
}
Handle pan gesture
![Page 24: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/24.jpg)
Drag and drop
- (void)handleDraggindHold:(NSTimer *)timer {
FLSDataSource *dataSource = self.collectionView.dataSource;
NSIndexPath *newIndexPath = [self.collectionView
indexPathForItemAtPoint:self.draggingView.center];
if (newIndexPath != nil &&
![newIndexPath isEqual:self.draggingIndexPath]) {
BOOL canMove = ...; /// Use data source
if (canMove) {
self.draggingIndexPath = newIndexPath;
[dataSource collectionView:self.collectionView
moveItemAtIndexPath:self.lastSourceIndexPath
toIndexPath:newIndexPath isHeld:YES];
self.lastSourceIndexPath = newIndexPath;
/// Invalidate layout
}
}
}
Handle hold
![Page 25: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/25.jpg)
Documents application
• Landscape and portrait items A4 scale
• Multiple waterfall columns for iPad and iPhone
• Number of columns must be changed on device
rotation
• Drag and drop items like on home screen
• Autoscroll while dragging
v 0.1
![Page 26: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/26.jpg)
Autoscroll
• Consider to use CADisplayLink instead of
NSTimer
• Invalidate dragging hold timer while autoscrolling
• Calculate autoscroll direction and velocity while
dragging
• Calculate dragging view’s frame and collection
view’s contentOffset
![Page 27: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/27.jpg)
Autoscroll
CGRect autoscrollFrame = UIEdgeInsetsInsetRect(self.collectionView.bounds,
self.autoscrollTriggerInsets);
CGPoint location = [gesture locationInView:self.collectionView];
CGFloat top = CGRectGetMinY(autoscrollFrame);
CGFloat bottom = CGRectGetMaxY(autoscrollFrame);
if (location.y < top) {
self.autosctollVelocity = 10 * (top - location.y);
[self scheduleAutoscrollTimerWithDirection:FLSAutoscrollDirectionUp];
} else if (location.y > bottom) {
self.autosctollVelocity = 10 * (location.y - bottom);
[self scheduleAutoscrollTimerWithDirection:FLSAutoscrollDirectionDown];
} else {
[self invalidateAutoscrollTimer];
}
Trigger autoscroll
![Page 28: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/28.jpg)
Autoscroll
CGFloat distance = rintf(self.autosctollVelocity / 60.0);
switch (self.autoscrollDirection) {
/// Visually stop autoscroll if bottom of the content was
reached
case FLSAutoscrollDirectionDown: {
break;
}
/// Visually stop autoscroll if top of the content was reached
default:
break;
}
CGPoint translation = CGPointMake(0, distance);
CGPoint newCenter = ...;
[self constrainPointToDragBounds:&newCenter];
self.draggingView.center = newCenter;
self.collectionView.contentOffset = ...;
Handle autoscroll
![Page 29: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/29.jpg)
Recap
• Cache all the possible values: calculate once and
reuse
• Auto layout is your friend
• Invalidate layout rationally
• Measure, measure and… measure
![Page 30: Collection view layout](https://reader030.fdocuments.in/reader030/viewer/2022032616/55a683531a28ab42498b46f3/html5/thumbnails/30.jpg)
More informationWWDC 2014 — Session 232
Advanced User Interfaces with Collection View
Source code: https://developer.apple.com/wwdc/resources/sample-code/
WWDC 2014 — Session 226
What's New in Table and Collection Views
Collection View Programming Guide for iOS
Creating Custom Layout
Yalantis
Excel Page Layout for Collection View
http://yalantis.com/blog/data-grid-with-freeze-columns-play-by-your-rules/
WWDC 2012 — Session 219
Advanced Collection Views and Building Custom Layout
7th iOS Practice Leaders
Introduction to Auto Layout
Presentation