iOS Combining Touch and Animation

1,908 views

Published on

Published in: Technology, Business
1 Comment
4 Likes
Statistics
Notes
  • This is only the beginning of collection views. Great share, the parallax design structure will bring true 'intuitive' interaction to apps.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
1,908
On SlideShare
0
From Embeds
0
Number of Embeds
27
Actions
Shares
0
Downloads
26
Comments
1
Likes
4
Embeds 0
No embeds

No notes for slide

iOS Combining Touch and Animation

  1. 1. TOUCH & ANIMATIONSaturday, April 6, 13 1
  2. 2. René Cacheaux Senior iOS Engineer rene.cacheaux@mutualmobile.comSaturday, April 6, 13 2
  3. 3. Touch can control anythingSaturday, April 6, 13 3
  4. 4. Rich experiencesSaturday, April 6, 13 4
  5. 5. Enhances livesSaturday, April 6, 13 5
  6. 6. MAkes apps excitingSaturday, April 6, 13 6
  7. 7. Shoulders of giantsSaturday, April 6, 13 7
  8. 8. The Plan for today is...Saturday, April 6, 13 8
  9. 9. Where to begin?Saturday, April 6, 13 9
  10. 10. Recognizers & MetricsSaturday, April 6, 13 10
  11. 11. 1 Location in View: global Metrics 2 Number of Touches 3 Location of Touch in View:Saturday, April 6, 13 11
  12. 12. 1 Translation in View: Pan 2 Velocity in View:Saturday, April 6, 13 12
  13. 13. 1 Scale Pinch 2 VelocitySaturday, April 6, 13 13
  14. 14. Long pressSaturday, April 6, 13 14
  15. 15. What to ControlSaturday, April 6, 13 15
  16. 16. Core AnimationSaturday, April 6, 13 16
  17. 17. Core animation Programming Guide WWDC Videos HeadersSaturday, April 6, 13 17
  18. 18. Core GraphicsSaturday, April 6, 13 18
  19. 19. Quartz 2D Programming Guide WWDC Videos HeadersSaturday, April 6, 13 19
  20. 20. Core ImageSaturday, April 6, 13 20
  21. 21. Core Image Programming Guide WWDC Videos HeadersSaturday, April 6, 13 21
  22. 22. real examplesSaturday, April 6, 13 22
  23. 23. PullSaturday, April 6, 13 23
  24. 24. Drag n DropSaturday, April 6, 13 24
  25. 25. PinchSaturday, April 6, 13 25
  26. 26. Parallactic SugarSaturday, April 6, 13 26
  27. 27. 1 Para-what? 2 Parallaxing Rainforest 3 Show Me the MoneySaturday, April 6, 13 27
  28. 28. 1 Para-what? 2 Parallaxing Rainforest 3 Show Me the MoneySaturday, April 6, 13 28
  29. 29. 1 Para-what? 2 Parallaxing Rainforest 3 Show Me the MoneySaturday, April 6, 13 29
  30. 30. Parallaxing rainForestSaturday, April 6, 13 30
  31. 31. 1 Para-what? 2 Parallaxing Rainforest 3 Show Me the MoneySaturday, April 6, 13 31
  32. 32. Parallaxing rainForest ArchitectureSaturday, April 6, 13 32
  33. 33. Banner Parallaxing Cell Components Banner Parallaxing CellSaturday, April 6, 13 33
  34. 34. rainforest PXColletionViewController UIView UICollectionView PXCollectionViewLayout PXCollectionViewCell PXCollectionViewCell UICollectionReusableView UICollectionReusableView PXCollectionViewCell PXCollectionViewCell UICollectionReusableView PXBannerViewSaturday, April 6, 13 34
  35. 35. But First...Saturday, April 6, 13 35
  36. 36. UI Collection View BasicsSaturday, April 6, 13 36
  37. 37. UI Collection View UICollectionViewDataSource UICollectionView UICollectionViewLayout UICollectionViewDelegate UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableViewSaturday, April 6, 13 37
  38. 38. UI Collection View 3 UICollectionViewDataSource 1 UICollectionView 2 UICollectionViewLayout UICollectionViewDelegate UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableViewSaturday, April 6, 13 38
  39. 39. Collection View UICollectionViewDataSource 1 UICollectionView UICollectionViewLayout UICollectionViewDelegate UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableViewSaturday, April 6, 13 39
  40. 40. class hierarchy NSObject UIResponder UIView UIScrollView UICollectionViewSaturday, April 6, 13 40
  41. 41. 1 Title Content Content A 2 Title Collection Content View 3 Title Content ContentSaturday, April 6, 13 41
  42. 42. 1 Title Content Content 2 Title Sections Content 3 Title Content ContentSaturday, April 6, 13 42
  43. 43. 1 Title Content Content 2 Title Cells Content 3 Title Content ContentSaturday, April 6, 13 43
  44. 44. 1 Title Content Content Supplementary 2 Title Views Content 3 Title Content ContentSaturday, April 6, 13 44
  45. 45. Layout UICollectionViewDataSource UICollectionView 2 UICollectionViewLayout UICollectionViewDelegate UICollectionViewCell UICollectionReusableViewSaturday, April 6, 13 45
  46. 46. Custom layoutsSaturday, April 6, 13 46
  47. 47. Layout AttributesSaturday, April 6, 13 47
  48. 48. Layout Attributes @interface UICollectionViewLayoutAttributes : NSObject <NSCopying> @property (nonatomic) CGRect frame; @property (nonatomic) CGPoint center; @property (nonatomic) CGSize size; @property (nonatomic) CATransform3D transform3D; @property (nonatomic) CGFloat alpha; @property (nonatomic) NSInteger zIndex; @property (nonatomic, getter=isHidden) BOOL hidden; @property (nonatomic, retain) NSIndexPath *indexPath; @property (nonatomic, readonly) UICollectionElementCategory representedElementCategory; @property (nonatomic, readonly) NSString *representedElementKind; + (instancetype)layoutAttributesForCellWithIndexPath:(NSIndexPath *)indexPath; + (instancetype)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind withIndexPath:(NSIndexPath *)indexPath; + (instancetype)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind withIndexPath:(NSIndexPath*)indexPath; @endSaturday, April 6, 13 48
  49. 49. Delegate & Datasource 3 UICollectionViewDataSource UICollectionView UICollectionViewLayout UICollectionViewDelegate UICollectionViewCell UICollectionReusableViewSaturday, April 6, 13 49
  50. 50. UI Collection View UICollectionViewDataSource UICollectionView UICollectionViewLayout UICollectionViewDelegate UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableView UICollectionViewCell UICollectionReusableViewSaturday, April 6, 13 50
  51. 51. Build ItSaturday, April 6, 13 51
  52. 52. Banner Parallax Visible Height Parallaxing Cell Components Banner Parallaxing CellSaturday, April 6, 13 52
  53. 53. Banner One Cell per Section Parallaxing Cell Components Banner Parallaxing CellSaturday, April 6, 13 53
  54. 54. rainforest PXColletionViewController Custom Layout UIView UICollectionView PXCollectionViewLayout PXCollectionViewCell PXCollectionViewCell UICollectionReusableView UICollectionReusableView PXCollectionViewCell PXCollectionViewCell UICollectionReusableView PXBannerViewSaturday, April 6, 13 54
  55. 55. Px Collection view layoutSaturday, April 6, 13 55
  56. 56. Layout HeaderSaturday, April 6, 13 56
  57. 57. Px Layout header static NSString * const kPXBannerSupplementaryViewKind = @"PXBanner"; @protocol PXCollectionViewDelegate <UICollectionViewDelegate> @optional - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout heightForBannerInSection:(NSInteger)section; @end ...Saturday, April 6, 13 57
  58. 58. Px Layout header ... @interface PXCollectionViewLayout : UICollectionViewLayout @property(nonatomic, assign) CGFloat parallaxVisibleHeight; @endSaturday, April 6, 13 58
  59. 59. A Pattern 1 Author Element View Class 2 Implement DataSource & Delegate 3 Write Layout AlgorithmSaturday, April 6, 13 59
  60. 60. Step 1 BannersSaturday, April 6, 13 60
  61. 61. Banner Parallaxing Cell Banners Banner Parallaxing CellSaturday, April 6, 13 61
  62. 62. author Banner viewSaturday, April 6, 13 62
  63. 63. rainforest PXColletionViewController UIView UICollectionView PXCollectionViewLayout PXCollectionViewCell UICollectionReusableView UICollectionReusableView UICollectionReusableView PXBannerViewSaturday, April 6, 13 63
  64. 64. Banner View HeaderSaturday, April 6, 13 64
  65. 65. Banner view #import <UIKit/UIKit.h> @interface PXBannerView : UICollectionReusableView - (void)setImageToImageNamed:(NSString *)imageNamed; @endSaturday, April 6, 13 65
  66. 66. Banner View ImplementationSaturday, April 6, 13 66
  67. 67. Banner view #import "PXBannerView.h" @interface PXBannerView () @property(nonatomic, strong) UIImageView *imageView; @end @implementation PXBannerView ... @endSaturday, April 6, 13 67
  68. 68. Banner view @implementation PXBannerView ... - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.clipsToBounds = YES; _imageView = [self newImageView]; [self addSubview:_imageView]; } return self; } - (UIImageView *)newImageView { UIImageView *imageView = [[UIImageView alloc] init]; imageView.contentMode = UIViewContentModeScaleAspectFill; return imageView; } ...@endSaturday, April 6, 13 68
  69. 69. Banner view @implementation PXBannerView ... - (void)setImageToImageNamed:(NSString *)imageNamed { UIImage *image = [UIImage imageNamed:imageNamed]; self.imageView.image = image; } ... @endSaturday, April 6, 13 69
  70. 70. Banner view @implementation PXBannerView ... - (void)layoutSubviews { [super layoutSubviews]; self.imageView.frame = CGRectMake(0.0f, 0.0f, self.bounds.size.width, self.bounds.size.height); } ... @endSaturday, April 6, 13 70
  71. 71. Banner view @implementation PXBannerView ... - (void)prepareForReuse { [super prepareForReuse]; self.imageView.image = nil; } ... @endSaturday, April 6, 13 71
  72. 72. implement the data source & DelegateSaturday, April 6, 13 72
  73. 73. rainforest PXColletionViewController UIView UICollectionView PXCollectionViewLayout PXCollectionViewCell PXBannerViewSaturday, April 6, 13 73
  74. 74. Before Implementing the Data Source and Delegate...Saturday, April 6, 13 74
  75. 75. We have to create the collection view.Saturday, April 6, 13 75
  76. 76. view controller implementationSaturday, April 6, 13 76
  77. 77. VIEW CONTROLLER #import "PXCollectionViewController.h" #import "PXCollectionViewLayout.h" #import "PXBannerView.h" static NSString * const kPXParallaxCellReuseID = @"PXCellID"; static NSString * const kPXBannerReuseID = @"PXBannerID"; @interface PXCollectionViewController ()<UICollectionViewDataSource, PXCollectionViewDelegate> @property(nonatomic, strong) UICollectionView *collectionView; @end @implementation PXCollectionViewController ... @endSaturday, April 6, 13 77
  78. 78. VIEW CONTROLLER @implementation PXCollectionViewController - (void)loadView { ... } - (void)viewDidLoad { ... } - (void)loadCollectionView { ... } - (void)viewWillLayoutSubviews { ... } #pragma mark UICollectionView Datasource ... #pragma mark PXCollectionView Delegate ... @endSaturday, April 6, 13 78
  79. 79. 1 Create Collection ViewCreation 2 Set Data Source & Delegate 3 Register ClassesSaturday, April 6, 13 79
  80. 80. Create collection view @implementation PXCollectionViewController ... - (void)loadCollectionView { // Create the Collection View. PXCollectionViewLayout *layout = [[PXCollectionViewLayout alloc] init]; layout.parallaxVisibleHeight = 500.0f; self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; ... } ... @endSaturday, April 6, 13 80
  81. 81. 1 Create Collection ViewCreation 2 Set Data Source & Delegate 3 Register ClassesSaturday, April 6, 13 81
  82. 82. DATASOURCE & DELEGATE @implementation PXCollectionViewController ... - (void)loadCollectionView { ... // Set DataSource and Delegate. self.collectionView.dataSource = self; self.collectionView.delegate = self; ... } ... @endSaturday, April 6, 13 82
  83. 83. 1 Create Collection ViewCreation 2 Set Data Source & Delegate 3 Register ClassesSaturday, April 6, 13 83
  84. 84. Register View classes @implementation PXCollectionViewController ... - (void)loadCollectionView { ... // Register Collection Reusable View Classes. [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kPXParallaxCellReuseID]; [self.collectionView registerClass:[PXBannerView class] forSupplementaryViewOfKind:kPXBannerSupplementaryViewKind withReuseIdentifier:kPXBannerReuseID]; // Install Collection View into View Hierarchy. [self.view addSubview:self.collectionView]; } ... @endSaturday, April 6, 13 84
  85. 85. Now we can ...Saturday, April 6, 13 85
  86. 86. Implement the data source and delegate.Saturday, April 6, 13 86
  87. 87. 1 Number of Sections Data Source 2 Number of Items in Section:Saturday, April 6, 13 87
  88. 88. Data source @implementation PXCollectionViewController #pragma mark UICollectionView Datasource - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ return 4; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 1; } ... @endSaturday, April 6, 13 88
  89. 89. 1 Cell for Item at Index Path: Data Source 2 View for Supplementary Element of Kind:Saturday, April 6, 13 89
  90. 90. Data source @implementation PXCollectionViewController #pragma mark UICollectionView Datasource ... - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kPXParallaxCellReuseID forIndexPath:indexPath]; return cell; } ... @endSaturday, April 6, 13 90
  91. 91. Data source @implementation PXCollectionViewController #pragma mark UICollectionView Datasource ... - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { PXBannerView *banner = [collectionView dequeueReusableSupplementaryViewOfKind:kPXBannerSupplementaryViewKind withReuseIdentifier:kPXBannerReuseID forIndexPath:indexPath]; [banner setImageToImageNamed:[NSString stringWithFormat:@"B%i.jpg", indexPath.section]]; return banner; } @endSaturday, April 6, 13 91
  92. 92. DelegateSaturday, April 6, 13 92
  93. 93. Custom Layout Collection View DelegateSaturday, April 6, 13 93
  94. 94. Px Layout header static NSString * const kPXBannerSupplementaryViewKind = @"PXBanner"; @protocol PXCollectionViewDelegate <UICollectionViewDelegate> @optional - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout heightForBannerInSection:(NSInteger)section; @end ...Saturday, April 6, 13 94
  95. 95. Delegate @implementation PXCollectionViewController #pragma mark PXCollectionView Delegate - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout heightForBannerInSection:(NSInteger)section { if (section == 0) { return 900.0f; } return 500.0f; } @endSaturday, April 6, 13 95
  96. 96. No Banners on Screen Yet.Saturday, April 6, 13 96
  97. 97. banner view LayoutSaturday, April 6, 13 97
  98. 98. rainforest PXColletionViewController Custom Layout UIView UICollectionView PXCollectionViewLayout PXCollectionViewCell PXBannerViewSaturday, April 6, 13 98
  99. 99. Layout implementationSaturday, April 6, 13 99
  100. 100. px Layout #import "PXCollectionViewLayout.h" Layout Attributes @interface PXCollectionViewLayout () // Layout Metrics. @property(nonatomic, strong) NSMutableArray *parallaxCellsLayoutAttributes; @property(nonatomic, strong) NSMutableArray *bannersLayoutAttributes; @property(nonatomic, assign) CGFloat contentHeight; @end @implementation PXCollectionViewLayout ... @endSaturday, April 6, 13 100
  101. 101. px Layout @implementation PXCollectionViewLayout - (void)prepareLayout { ... } - (void)prepareLayoutForBannerViewInSection:(NSUInteger)section { ... } - (CGSize)collectionViewContentSize { ... } ... @endSaturday, April 6, 13 101
  102. 102. px Layout @implementation PXCollectionViewLayout ... - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { ... } - (UICollectionViewLayoutAttributes *) layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { ... } - (UICollectionViewLayoutAttributes *) layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { ... } ... @endSaturday, April 6, 13 102
  103. 103. px Layout @implementation PXCollectionViewLayout ... - (void)clearOutLayoutCalculations { ... } - (void)setParallaxVisibleHeight:(CGFloat)parallaxVisibleHeight { ... } @endSaturday, April 6, 13 103
  104. 104. px Layout @implementation PXCollectionViewLayout ... - (void)clearOutLayoutCalculations { self.bannersLayoutAttributes = [NSMutableArray array]; self.parallaxCellsLayoutAttributes = [NSMutableArray array]; self.parallaxingCellIndicies = [NSMutableArray array]; } - (void)setParallaxVisibleHeight:(CGFloat)parallaxVisibleHeight { _parallaxVisibleHeight = parallaxVisibleHeight; [self invalidateLayout]; } ... @endSaturday, April 6, 13 104
  105. 105. RememberSaturday, April 6, 13 105
  106. 106. Layout Attributes @interface UICollectionViewLayoutAttributes : NSObject <NSCopying> @property (nonatomic) CGRect frame; @property (nonatomic) CGPoint center; @property (nonatomic) CGSize size; @property (nonatomic) CATransform3D transform3D; @property (nonatomic) CGFloat alpha; @property (nonatomic) NSInteger zIndex; @property (nonatomic, getter=isHidden) BOOL hidden; @property (nonatomic, retain) NSIndexPath *indexPath; @property (nonatomic, readonly) UICollectionElementCategory representedElementCategory; @property (nonatomic, readonly) NSString *representedElementKind; + (instancetype)layoutAttributesForCellWithIndexPath:(NSIndexPath *)indexPath; + (instancetype)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind withIndexPath:(NSIndexPath *)indexPath; + (instancetype)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind withIndexPath:(NSIndexPath*)indexPath; @endSaturday, April 6, 13 106
  107. 107. 1 Prepare Layout Layout calcs 2 Content SizeSaturday, April 6, 13 107
  108. 108. Prepare layout @implementation PXCollectionViewLayout ... - (void)prepareLayout { [super prepareLayout]; // Clear out old layout. [self clearOutLayoutCalculations]; // Reset content height. self.contentHeight = 0.0f; // Get the number of sections from the datasource. NSUInteger numberOfSections = [self.collectionView.dataSource numberOfSectionsInCollectionView:self.collectionView]; // Calculate the layout for each banner. for (int i = 0; i < numberOfSections; i++) { [self prepareLayoutForBannerViewInSection:i]; } } ... @endSaturday, April 6, 13 108
  109. 109. Banner view layout @implementation PXCollectionViewLayout ... - (void)prepareLayoutForBannerViewInSection:(NSUInteger)section { id<PXCollectionViewDelegate> delegate = (id<PXCollectionViewDelegate>)self.collectionView.delegate; CGFloat contentWidth = self.collectionView.frame.size.width; CGFloat bannerHeight = [delegate collectionView:self.collectionView layout:self heightForBannerInSection:section]; ... } ... @end >Saturday, April 6, 13 109
  110. 110. Banner view layout @implementation PXCollectionViewLayout ... - (void)prepareLayoutForBannerViewInSection:(NSUInteger)section { ... // Banner Layout attributes. UICollectionViewLayoutAttributes *bannerAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:kPXBannerSupplementaryViewKind withIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]]; bannerAttributes.frame = CGRectMake(0.0f, self.contentHeight, contentWidth, bannerHeight); bannerAttributes.zIndex = 1; self.bannersLayoutAttributes[section] = bannerAttributes; self.contentHeight += (bannerHeight + self.parallaxVisibleHeight); } ... @end >Saturday, April 6, 13 110
  111. 111. 1 Prepare Layout Layout calcs 2 Content SizeSaturday, April 6, 13 111
  112. 112. Layout CONTENT SIZE @implementation PXCollectionViewLayout ... - (CGSize)collectionViewContentSize { return CGSizeMake(self.collectionView.frame.size.width, self.contentHeight); } ... @endSaturday, April 6, 13 112
  113. 113. And now the core methods....Saturday, April 6, 13 113
  114. 114. everything is already calculated by the time we hit these methodsSaturday, April 6, 13 114
  115. 115. 1 Elements in Rect: 2 LAYOUT Item at Index Path:ATTRIBUTES For: 3 Supplementary View of Kind: at Index Path:Saturday, April 6, 13 115
  116. 116. 1 Title Content Rect Content Elements 2 Title in Content Rect 3 Title Content ContentSaturday, April 6, 13 116
  117. 117. Elements in rect @implementation PXCollectionViewLayout ... - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray *layoutAttributesInRect = [NSMutableArray array]; // Banners. for (UICollectionViewLayoutAttributes *layoutAttributes in self.bannersLayoutAttributes) { if (CGRectIntersectsRect(layoutAttributes.frame, rect)) { [layoutAttributesInRect addObject:layoutAttributes]; } } return [layoutAttributesInRect copy]; } ... @endSaturday, April 6, 13 117
  118. 118. 1 Elements in Rect: 2 LAYOUT Item at Index Path:ATTRIBUTES For: 3 Supplementary View of Kind: at Index Path:Saturday, April 6, 13 118
  119. 119. at index path @implementation PXCollectionViewLayout ... - (UICollectionViewLayoutAttributes *) layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; return layoutAttributes; } - (UICollectionViewLayoutAttributes *) layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes *layoutAttributes = self.bannersLayoutAttributes[indexPath.section]; return layoutAttributes; } ... @endSaturday, April 6, 13 119
  120. 120. Quick tour in XcodeSaturday, April 6, 13 120
  121. 121. Step 2 Parallaxing CellsSaturday, April 6, 13 121
  122. 122. Banner Parallaxing Cell Components Banner Parallaxing CellSaturday, April 6, 13 122
  123. 123. author Collection View CellSaturday, April 6, 13 123
  124. 124. rainforest PXColletionViewController UIView UICollectionView PXCollectionViewLayout PXCollectionViewCell PXBannerView PXCollectionViewCell PXCollectionViewCell PXCollectionViewCellSaturday, April 6, 13 124
  125. 125. PXCollectionViewCell Content View PXCroppedImageContainerViewSaturday, April 6, 13 125
  126. 126. 1 Cropped Image Container View Cell 2 Collection View Cell SubclassSaturday, April 6, 13 126
  127. 127. Cropped Image Container Container View Image ViewSaturday, April 6, 13 127
  128. 128. Cropped Image Container Reference Frame Image ViewSaturday, April 6, 13 128
  129. 129. Cropped Image Container Container View Image ViewSaturday, April 6, 13 129
  130. 130. Container View Cropped Image Container Reference Frame Image ViewSaturday, April 6, 13 130
  131. 131. container view headerSaturday, April 6, 13 131
  132. 132. Image container View #import <UIKit/UIKit.h> @interface PXCroppedImageContainerView : UIView @property(nonatomic, assign) CGRect referenceFrame; @property(nonatomic, strong, readonly) UIImageView *imageView; @property(nonatomic, assign) CGFloat imageViewScale; - (void)setImageToImageNamed:(NSString *)imageNamed; @endSaturday, April 6, 13 132
  133. 133. container view implementationSaturday, April 6, 13 133
  134. 134. Image container View @implementation PXCroppedImageContainerView ... - (void)layoutSubviews { [super layoutSubviews]; if (CGRectEqualToRect(self.referenceFrame, CGRectZero)) { return; } // Size. CGSize imageViewSize = [self sizeForImageViewForScale:self.imageViewScale]; self.imageView.frame = CGRectMake(0.0f, 0.0f, imageViewSize.width, imageViewSize.height); // Position. CGPoint imageViewCenter = [self centerPointForImageView]; self.imageView.center = imageViewCenter; } ... @endSaturday, April 6, 13 134
  135. 135. Image container View @implementation PXCroppedImageContainerView ... - (CGSize)sizeForImageViewForScale:(CGFloat)scale { CGSize imageViewSize = [self multiplySizeOfRect:self.referenceFrame byFactor:(scale * 3.0f)]; if (imageViewSize.width < self.referenceFrame.size.width) { imageViewSize = self.referenceFrame.size; } return imageViewSize; } - (CGPoint)centerPointForImageView { return [self centerPointOfRect:self.referenceFrame]; } ... @endSaturday, April 6, 13 135
  136. 136. 1 Cropped Image Container View Cell 2 Collection View Cell SubclassSaturday, April 6, 13 136
  137. 137. cell headerSaturday, April 6, 13 137
  138. 138. Collection View Cell #import <UIKit/UIKit.h> @class PXCroppedImageContainerView; @interface PXCollectionViewCell : UICollectionViewCell @property(nonatomic, strong, readonly) PXCroppedImageContainerView *imageContainerView; - (void)setImageToImageNamed:(NSString *)imageNamed; @endSaturday, April 6, 13 138
  139. 139. cell implementationSaturday, April 6, 13 139
  140. 140. Collection View Cell #import "PXCollectionViewCell.h" #import "PXCroppedImageContainerView.h" @interface PXCollectionViewCell () @property(nonatomic, strong, readwrite) PXCroppedImageContainerView *imageContainerView; @end @implementation PXCollectionViewCell ... @endSaturday, April 6, 13 140
  141. 141. Collection View Cell @implementation PXCollectionViewCell ... - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { _imageContainerView = [self newCroppedImageContainerView]; [self.contentView addSubview:_imageContainerView]; } return self; } - (PXCroppedImageContainerView *)newCroppedImageContainerView { PXCroppedImageContainerView *containerView = [[PXCroppedImageContainerView alloc] init]; return containerView; } ... @endSaturday, April 6, 13 141
  142. 142. Collection View Cell @implementation PXCollectionViewCell ... - (void)setImageToImageNamed:(NSString *)imageNamed { [self.imageContainerView setImageToImageNamed:imageNamed]; } ... @endSaturday, April 6, 13 142
  143. 143. Collection View Cell @implementation PXCollectionViewCell ... - (void)prepareForReuse { [super prepareForReuse]; self.imageContainerView.imageView.image = nil; } ... @endSaturday, April 6, 13 143
  144. 144. Collection View Cell @implementation PXCollectionViewCell ... #pragma mark Layout - (void)layoutSubviews { [super layoutSubviews]; self.imageContainerView.frame = self.contentView.bounds; } ... @endSaturday, April 6, 13 144
  145. 145. Don’t forget!Saturday, April 6, 13 145
  146. 146. To register the cell class.Saturday, April 6, 13 146
  147. 147. Register cell class @implementation PXCollectionViewController ... - (void)loadCollectionView { ... [self.collectionView registerClass:[PXCollectionViewCell class] forCellWithReuseIdentifier:kPXParallaxCellReuseID]; } ... @endSaturday, April 6, 13 147
  148. 148. implement the data source & DelegateSaturday, April 6, 13 148
  149. 149. rainforest PXColletionViewController UIView UICollectionView PXCollectionViewLayout PXCollectionViewCell PXBannerViewSaturday, April 6, 13 149
  150. 150. Cell for index Path @implementation PXCollectionViewController ... - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { // Dequeue cell. PXCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kPXParallaxCellReuseID forIndexPath:indexPath]; // Configure cell. cell.backgroundColor = [UIColor lightGrayColor]; cell.imageContainerView.referenceFrame = CGRectMake(0.0f, 0.0f, self.collectionView.frame.size.width, self.collectionView.frame.size.height); [cell setImageToImageNamed: [NSString stringWithFormat:@"%i.jpg", indexPath.section]]; return cell; } ... @endSaturday, April 6, 13 150
  151. 151. Nothing will show yet because we...Saturday, April 6, 13 151
  152. 152. Have to implement the layout algorithm.Saturday, April 6, 13 152
  153. 153. Parallax LayoutSaturday, April 6, 13 153
  154. 154. rainforest PXColletionViewController Custom Layout UIView UICollectionView PXCollectionViewLayout PXCollectionViewCell PXBannerViewSaturday, April 6, 13 154
  155. 155. Banner Parallaxing Cell Components Banner Parallaxing CellSaturday, April 6, 13 155
  156. 156. Banner Parallaxing Cell Banners Banner Parallaxing CellSaturday, April 6, 13 156
  157. 157. Banner Cell Banner Banner Banner Scroll View ContentsSaturday, April 6, 13 157
  158. 158. Banner Cell Cell 2 Banner Banner Banner Scroll View ContentsSaturday, April 6, 13 158
  159. 159. Banner Cell Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 159
  160. 160. Banner Cell Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 160
  161. 161. Banner Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 161
  162. 162. Banner Banner Cell 2 Cell 3 Banner Banner Scroll View ContentsSaturday, April 6, 13 162
  163. 163. Banner Banner Cell 2 Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 163
  164. 164. Banner Banner Cell 2 Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 164
  165. 165. Banner Banner Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 165
  166. 166. First we have to know how to...Saturday, April 6, 13 166
  167. 167. Anchor scroll view subviews.Saturday, April 6, 13 167
  168. 168. Scroll View MechanicsSaturday, April 6, 13 168
  169. 169. BOUNDS scroll View mechanics Scroll View ContentsSaturday, April 6, 13 169
  170. 170. Anchoring SubviewsSaturday, April 6, 13 170
  171. 171. Subview BOUNDS anchoring subviews Scroll View ContentsSaturday, April 6, 13 171
  172. 172. 1 Anchor cell Layout steps 2 Crop 3 ParallaxSaturday, April 6, 13 172
  173. 173. Anchor collection view cells using custom layout...Saturday, April 6, 13 173
  174. 174. Every time the bounds changes, update the subview frameSaturday, April 6, 13 174
  175. 175. So we need a hook!Saturday, April 6, 13 175
  176. 176. Should Invalidate Layout for Bounds Change:Saturday, April 6, 13 176
  177. 177. Returning YES will invalidate your layoutSaturday, April 6, 13 177
  178. 178. So, on bounds changes...Saturday, April 6, 13 178
  179. 179. -invalidateLayout Subview -invalidateLayout -invalidateLayout -invalidateLayout -invalidateLayout BOUNDS invalidate layout Scroll View ContentsSaturday, April 6, 13 179
  180. 180. AND...Saturday, April 6, 13 180
  181. 181. Invalidate layout will call prepare layout and content sizeSaturday, April 6, 13 181
  182. 182. What’s cool is...Saturday, April 6, 13 182
  183. 183. Will pick up scroll view momentum animationsSaturday, April 6, 13 183
  184. 184. SO...Saturday, April 6, 13 184
  185. 185. return YESSaturday, April 6, 13 185
  186. 186. invalidate layout @implementation PXCollectionViewLayout ... - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; }.. @endSaturday, April 6, 13 186
  187. 187. On invalidate layout @implementation PXCollectionViewLayout ... - (void)prepareLayout { [super prepareLayout]; // Clear out old layout. [self clearOutLayoutCalculations]; // Reset content height. self.contentHeight = 0.0f; // Get the number of sections from the datasource. NSUInteger numberOfSections = [self.collectionView.dataSource numberOfSectionsInCollectionView:self.collectionView]; // Calculate the layout for each banner. for (int i = 0; i < numberOfSections; i++) { [self prepareLayoutForBannerViewInSection:i]; } } ... @endSaturday, April 6, 13 187
  188. 188. Now we can implement the anchoring layout.Saturday, April 6, 13 188
  189. 189. Anchor @implementation PXCollectionViewLayout ... - (void)prepareLayout { [super prepareLayout]; [self clearOutLayoutCalculations]; self.contentHeight = 0.0f; NSUInteger numberOfSections = [self.collectionView.dataSource numberOfSectionsInCollectionView:self.collectionView]; // Layout for Banners. for (int i = 0; i < numberOfSections; i++) { [self prepareLayoutForBannerViewInSection:i]; } // Layout for Cells. Calculate Each Cell’s Layout for (int i = 0; i < numberOfSections; i++) { [self prepareLayoutForParallaxCellInSection:i]; } } ... @endSaturday, April 6, 13 189
  190. 190. Anchor @implementation PXCollectionViewLayout ... Create Layout Attributes - (void)prepareLayoutForParallaxCellInSection:(NSUInteger)section { UICollectionViewLayoutAttributes *parallaxCellAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]]; [self configureLayoutAttributesForParallaxingCellInSection:section layoutAttributes:parallaxCellAttributes]; self.parallaxCellsLayoutAttributes[section] = parallaxCellAttributes; } ... Store Calculate @endSaturday, April 6, 13 190
  191. 191. Where the magic happens @implementation PXCollectionViewLayout ... - (void)configureLayoutAttributesForParallaxingCellInSection:(NSUInteger)section layoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { // Anchor. CGFloat bottomOfBounds = CGRectGetMaxY(self.collectionView.bounds); CGRect newImageFrame = CGRectMake(0.0f, (bottomOfBounds - self.collectionView.bounds.size.height), self.collectionView.bounds.size.width, self.collectionView.bounds.size.height); layoutAttributes.frame = newImageFrame; layoutAttributes.zIndex = -1 * section; } ... @end >Saturday, April 6, 13 191
  192. 192. DemoSaturday, April 6, 13 192
  193. 193. Why there’s a problemSaturday, April 6, 13 193
  194. 194. Banner Cell 2 Cell Cell Banner Banner Banner Scroll View ContentsSaturday, April 6, 13 194
  195. 195. Banner Banner Cell 2 Cell Cell Banner Banner Scroll View ContentsSaturday, April 6, 13 195
  196. 196. Banner Banner Cell 2 Cell Cell Banner Banner Scroll View ContentsSaturday, April 6, 13 196
  197. 197. Banner Banner Cell 2 Cell Cell Banner Banner Scroll View ContentsSaturday, April 6, 13 197
  198. 198. Banner Banner Cell 2 Cell Cell Banner Banner Scroll View ContentsSaturday, April 6, 13 198
  199. 199. Which Cell is Parallaxing?Saturday, April 6, 13 199
  200. 200. Banner Banner BOUNDS Determine Parallaxing Banner Cells Banner Scroll View ContentsSaturday, April 6, 13 200
  201. 201. Parallaxing Window Must be On ScreenSaturday, April 6, 13 201
  202. 202. BUT There’s no frame.Saturday, April 6, 13 202
  203. 203. SoSaturday, April 6, 13 203
  204. 204. Banner Banner BOUNDS Determine Parallaxing Banner Cells Banner Scroll View ContentsSaturday, April 6, 13 204
  205. 205. Banner BOUNDS About to Banner show Determine CELL Parallaxing Banner Cells Banner Scroll View ContentsSaturday, April 6, 13 205
  206. 206. Banner Banner Determine BOUNDS CELL Parallaxing Banner About to Cells disappear Banner Scroll View ContentsSaturday, April 6, 13 206
  207. 207. px Layout #import "PXCollectionViewLayout.h" New Property @interface PXCollectionViewLayout () // Layout Metrics. @property(nonatomic, strong) NSMutableArray *parallaxCellsLayoutAttributes; @property(nonatomic, strong) NSMutableArray *bannersLayoutAttributes; @property(nonatomic, assign) CGFloat contentHeight; @property(nonatomic, strong) NSMutableArray *parallaxingCellIndicies; @end @implementation PXCollectionViewLayout ... @endSaturday, April 6, 13 207
  208. 208. Now we can implement the logic.Saturday, April 6, 13 208
  209. 209. First, we have to look at the top of the cell.Saturday, April 6, 13 209
  210. 210. Banner BOUNDS About to Banner show Determine CELL Parallaxing Banner Cells Banner Scroll View ContentsSaturday, April 6, 13 210
  211. 211. Parallaxing indicies @implementation PXCollectionViewLayout ... New Method - (void)updateParallaxingCellIndicies { CGFloat bottomOfBounds = CGRectGetMaxY(self.collectionView.bounds); CGFloat topOfBounds = CGRectGetMinY(self.collectionView.bounds); NSMutableArray *parallaxingIndicies = [NSMutableArray array]; // Look for Cells that are Parallaxing or have Parallaxed. for (int i = 0; i < [self.bannersLayoutAttributes count]; i++) { UICollectionViewLayoutAttributes *bannerLayoutAttributes = self.bannersLayoutAttributes[i]; CGFloat bottomOfBanner = CGRectGetMaxY(bannerLayoutAttributes.frame); if (bottomOfBanner <= bottomOfBounds) { [parallaxingIndicies addObject:@(i)]; } } ... } ... @endSaturday, April 6, 13 211
  212. 212. Second, we have to look at the bottom of the cell.Saturday, April 6, 13 212
  213. 213. Banner Banner Determine BOUNDS CELL Parallaxing Banner About to Cells disappear Banner Scroll View ContentsSaturday, April 6, 13 213
  214. 214. Parallaxing indicies @implementation PXCollectionViewLayout ... - (void)updateParallaxingCellIndicies { ... // Remove Cells which are not Parallaxing. for (int i = 0; i < [self.bannersLayoutAttributes count]; i++) { UICollectionViewLayoutAttributes *bannerLayoutAttributes = self.bannersLayoutAttributes[i]; CGFloat topOfBanner = CGRectGetMinY(bannerLayoutAttributes.frame); if (topOfBanner <= topOfBounds) { [parallaxingIndicies removeObject:@(i - 1)]; } }! self.parallaxingCellIndicies = parallaxingIndicies; } ... @endSaturday, April 6, 13 214
  215. 215. Now we have an array of indicesSaturday, April 6, 13 215
  216. 216. A helper method.Saturday, April 6, 13 216
  217. 217. Parallaxing indicies @implementation PXCollectionViewLayout ... - (BOOL)isParallaxingSection:(NSUInteger)section { if ([self.parallaxingCellIndicies containsObject:@(section)]) { return YES; } return NO; } ... @endSaturday, April 6, 13 217
  218. 218. Last step to anchor, non parallaxing cells.Saturday, April 6, 13 218
  219. 219. Anchor Parallaxing Cells @implementation PXCollectionViewLayout ... Only Layout Cells on Screen - (void)prepareLayoutForParallaxCellInSection:(NSUInteger)section { UICollectionViewLayoutAttributes *parallaxCellAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]]; if ([self isParallaxingSection:section]) { [self configureLayoutAttributesForParallaxingCellInSection:section layoutAttributes:parallaxCellAttributes]; } else { parallaxCellAttributes.frame = CGRectZero; } self.parallaxCellsLayoutAttributes[section] = parallaxCellAttributes; Calculate } ... Store @endSaturday, April 6, 13 219
  220. 220. We have anchored cells and only the ones that are parallaxing are laid out.Saturday, April 6, 13 220
  221. 221. demoSaturday, April 6, 13 221
  222. 222. Why there’s a problemSaturday, April 6, 13 222
  223. 223. Banner Cell 2 Cell Banner Banner Banner Scroll View ContentsSaturday, April 6, 13 223
  224. 224. Banner Banner Cell 2 Cell Banner Banner Scroll View ContentsSaturday, April 6, 13 224
  225. 225. Banner Banner Cell 2 Cell Banner Banner Scroll View ContentsSaturday, April 6, 13 225
  226. 226. Banner Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 226
  227. 227. Banner Banner Cell 3 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 227
  228. 228. Banner Banner Banner Cell 3 2 Banner Scroll View ContentsSaturday, April 6, 13 228
  229. 229. Banner Banner Banner Cell 3 2 Banner Scroll View ContentsSaturday, April 6, 13 229
  230. 230. Banner Banner Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 230
  231. 231. 1 Anchor cell Layout steps 2 Crop 3 ParallaxSaturday, April 6, 13 231
  232. 232. Z-Index Matters!Saturday, April 6, 13 232
  233. 233. z-index @implementation PXCollectionViewLayout ... - (void)configureLayoutAttributesForParallaxingCellInSection:(NSUInteger)section layoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { // Anchor. CGFloat bottomOfBounds = CGRectGetMaxY(self.collectionView.bounds); CGRect newImageFrame = CGRectMake(0.0f, (bottomOfBounds - self.collectionView.bounds.size.height), self.collectionView.bounds.size.width, self.collectionView.bounds.size.height); layoutAttributes.frame = newImageFrame; layoutAttributes.zIndex = -1 * section; } ... @end First One on Top >Saturday, April 6, 13 233
  234. 234. Banner Cell Cell 2 Banner Banner Banner Scroll View ContentsSaturday, April 6, 13 234
  235. 235. Banner Cell Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 235
  236. 236. Banner Cell Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 236
  237. 237. Banner Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 237
  238. 238. Banner Banner Cell 2 Cell 3 Banner Banner Scroll View ContentsSaturday, April 6, 13 238
  239. 239. Banner Banner Cell 2 Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 239
  240. 240. Banner Banner Cell 2 Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 240
  241. 241. Banner Banner Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 241
  242. 242. What’s the logic?Saturday, April 6, 13 242
  243. 243. Banner Cell Banner Cell 2 Bottom of Banner Bottom of Anchor Banner Banner Scroll View ContentsSaturday, April 6, 13 243
  244. 244. Crop @implementation PXCollectionViewLayout ... - (void)configureLayoutAttributesForParallaxingCellInSection:(NSUInteger)section layoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { // Anchor. ... // Crop. Test for Crop // If theres a next banner. if (section < [self.bannersLayoutAttributes count] - 1) { UICollectionViewLayoutAttributes *nextCellsBannerLayoutAttributes = self.bannersLayoutAttributes[section + 1]; CGRect nextBannerFrame = nextCellsBannerLayoutAttributes.frame; // Crop if necessary. if (CGRectGetMaxY(newImageFrame) > CGRectGetMaxY(nextBannerFrame)) { CGFloat amountToCrop = CGRectGetMaxY(newImageFrame) - CGRectGetMaxY(nextBannerFrame); newImageFrame.size.height -= amountToCrop; } } Make Cell Shorter ... }... @end >Saturday, April 6, 13 244
  245. 245. demoSaturday, April 6, 13 245
  246. 246. 1 Anchor cell Layout steps 2 Crop 3 ParallaxSaturday, April 6, 13 246
  247. 247. Banner Cell Cell 2 Banner Banner Banner Scroll View ContentsSaturday, April 6, 13 247
  248. 248. Banner Cell Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 248
  249. 249. Banner Cell Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 249
  250. 250. Banner Banner Cell 2 Banner Banner Scroll View ContentsSaturday, April 6, 13 250
  251. 251. Banner Banner Cell 2 Cell 3 Banner Banner Scroll View ContentsSaturday, April 6, 13 251
  252. 252. Banner Banner Cell 2 Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 252
  253. 253. Banner Banner Cell 2 Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 253
  254. 254. Banner Banner Banner Cell 3 Banner Scroll View ContentsSaturday, April 6, 13 254
  255. 255. 1 Determine Percentage 2 Define Offset Parallax steps 3 Apply Current OffsetSaturday, April 6, 13 255
  256. 256. Banner BOUNDS Banner determine Percentage 0% Banner Banner Scroll View ContentsSaturday, April 6, 13 256
  257. 257. Banner Banner BOUNDS determine Percentage 50% Banner Banner Scroll View ContentsSaturday, April 6, 13 257
  258. 258. Banner Banner determine Percentage 100% Banner BOUNDS Banner Scroll View ContentsSaturday, April 6, 13 258
  259. 259. Banner Current BOUNDS Banner Banner Frame determine Max Percentage Banner Y Banner Scroll View ContentsSaturday, April 6, 13 259
  260. 260. Banner BOUNDS Banner determine next Banner Possible Percentage Banner Y Origin Banner Scroll View ContentsSaturday, April 6, 13 260
  261. 261. Banner BOUNDS Banner determine Banner + Percentage Banner Scroll View ContentsSaturday, April 6, 13 261
  262. 262. Banner Banner determine Banner + Percentage BOUNDS Bounds Height Banner Scroll View ContentsSaturday, April 6, 13 262
  263. 263. Banner Banner determine Banner Whole Percentage BOUNDS Height Banner Scroll View ContentsSaturday, April 6, 13 263
  264. 264. Percentage @implementation PXCollectionViewLayout ... - (void)configureLayoutAttributesForParallaxingCellInSection:(NSUInteger)section layoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { ... // Parallax. // Determine Percentage. UICollectionViewLayoutAttributes *thisCellsBannerLayoutAttributes = self.bannersLayoutAttributes[section]; CGRect currentBannerFrame = thisCellsBannerLayoutAttributes.frame; // Get the Whole Height. CGFloat nextPossibleBannerYOrigin = CGRectGetMaxY(currentBannerFrame) + self.parallaxVisibleHeight; ... }... @end >Saturday, April 6, 13 264
  265. 265. Percentage @implementation PXCollectionViewLayout ... - (void)configureLayoutAttributesForParallaxingCellInSection:(NSUInteger)section layoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { ... // Parallax. // Determine Percentage. ... Entire Distance CGFloat parallaxWholeHeight = (nextPossibleBannerYOrigin + self.collectionView.bounds.size.height); parallaxWholeHeight -= CGRectGetMaxY(currentBannerFrame); ... } ... @end >Saturday, April 6, 13 265
  266. 266. Banner Current BOUNDS Banner Banner Frame Starting Max Point Banner Y Banner Scroll View ContentsSaturday, April 6, 13 266
  267. 267. Percentage @implementation PXCollectionViewLayout ... - (void)configureLayoutAttributesForParallaxingCellInSection:(NSUInteger)section layoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { ... // Parallax. ... Percentage // Calculate Percentage. CGFloat percentParallax = (bottomOfBounds - CGRectGetMaxY(currentBannerFrame)) / parallaxWholeHeight; ... }... @end >Saturday, April 6, 13 267

×