├── .gitignore ├── CHANGELOG.md ├── Classes ├── ESConveyorAdapter.h ├── ESConveyorAdapter.m ├── ESConveyorBelt.h ├── ESConveyorBeltAttributes.h ├── ESConveyorBeltAttributes.m ├── ESConveyorController.h ├── ESConveyorController.m ├── ESConveyorEffects.h ├── ESConveyorEffects.m ├── ESConveyorElement.h ├── ESConveyorElement.m ├── ESConveyorFlowLayout.h ├── ESConveyorFlowLayout.m ├── ESConveyorPageCell.h ├── ESConveyorPageCell.m ├── ESConveyorPageControlElement.h ├── ESConveyorPageControlElement.m ├── ESConveyorView.h └── ESConveyorView.m ├── ESConveyorBelt.gif ├── ESConveyorBelt.podspec ├── Example ├── ESConveyorBeltSample.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── ESConveyorBeltSample │ ├── ESAppDelegate.h │ ├── ESAppDelegate.m │ ├── ESConveyorBeltSample-Info.plist │ ├── ESConveyorBeltSample-Prefix.pch │ ├── ESConveyorSample1Builder.h │ ├── ESConveyorSample1Builder.m │ ├── ESConveyorSample2Builder.h │ ├── ESConveyorSample2Builder.m │ ├── ESConveyorSampleViewController.h │ ├── ESConveyorSampleViewController.m │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json │ ├── Resources │ ├── bacon@2x.png │ ├── beach_bg.png │ ├── beach_chair@2x.png │ ├── cocktail@2x.png │ ├── flip_flops@2x.png │ ├── flippers@2x.png │ ├── goldengate@2x.jpg │ ├── surfboard@2x.png │ └── umbrella@2x.png │ ├── en.lproj │ └── InfoPlist.strings │ └── main.m ├── LICENSE ├── README.md └── Rakefile /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | **/Pods 23 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # ESConveyorBelt CHANGELOG 2 | 3 | ## 0.1.0 4 | 5 | Initial release. 6 | -------------------------------------------------------------------------------- /Classes/ESConveyorAdapter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class ESConveyorController; 9 | 10 | 11 | @interface ESConveyorAdapter : NSObject 12 | 13 | @property(nonatomic) NSInteger numberOfPages; 14 | 15 | @property(nonatomic, strong) NSArray *elements; 16 | 17 | - (id)initWithCollectionView:(UICollectionView *)collectionView numberOfPages:(NSInteger)pages elements:(NSArray *)elements; 18 | 19 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorAdapter.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorAdapter.h" 7 | #import "ESConveyorController.h" 8 | #import "ESConveyorView.h" 9 | #import "ESConveyorFlowLayout.h" 10 | #import "ESConveyorView.h" 11 | #import "ESConveyorElement.h" 12 | #import "ESConveyorPageCell.h" 13 | 14 | 15 | static NSString *const ESConveyorElementReuseIdentifier = @"ESConveyorElementReuseIdentifier"; 16 | NSString *kESConveyorCell = @"ESConveyorCell"; 17 | 18 | @interface ESConveyorAdapter () 19 | @property(nonatomic, weak) UICollectionView *collectionView; 20 | @end 21 | 22 | @implementation ESConveyorAdapter 23 | { 24 | 25 | } 26 | - (id)initWithCollectionView:(UICollectionView *)collectionView numberOfPages:(NSInteger)pages elements:(NSArray *)elements 27 | { 28 | 29 | self = [super init]; 30 | if (self) 31 | { 32 | self.collectionView = collectionView; 33 | self.numberOfPages = pages; 34 | self.elements = elements; 35 | 36 | self.collectionView.delegate = self; 37 | self.collectionView.dataSource = self; 38 | self.collectionView.pagingEnabled = YES; 39 | 40 | [self.collectionView registerClass:[ESConveyorPageCell class] forCellWithReuseIdentifier:kESConveyorCell]; 41 | [self.collectionView registerClass:[ESConveyorView class] forSupplementaryViewOfKind:NSStringFromClass(ESConveyorElement.class) withReuseIdentifier:ESConveyorElementReuseIdentifier]; 42 | 43 | } 44 | 45 | return self; 46 | } 47 | 48 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 49 | { 50 | return 1; 51 | } 52 | 53 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 54 | { 55 | return self.numberOfPages; 56 | } 57 | 58 | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath 59 | { 60 | if ([ESConveyorElementKind isEqualToString:kind]) { 61 | return [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:ESConveyorElementReuseIdentifier forIndexPath:indexPath]; 62 | } 63 | 64 | NSAssert(NO, @"This should never happen"); 65 | return nil; 66 | } 67 | 68 | 69 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 70 | { 71 | return [collectionView dequeueReusableCellWithReuseIdentifier:kESConveyorCell forIndexPath:indexPath]; 72 | } 73 | 74 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorBelt.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorController.h" 7 | #import "ESConveyorPageCell.h" 8 | #import "ESConveyorElement.h" 9 | #import "ESConveyorPageControlElement.h" 10 | #import "ESConveyorController.h" 11 | 12 | 13 | typedef NS_ENUM(NSUInteger, EZEffect) { 14 | ESConveyorEffectFade, 15 | ESConveyorEffectEdgeTop, 16 | ESConveyorEffectEdgeLeft, 17 | ESConveyorEffectEdgeRight, 18 | ESConveyorEffectEdgeBottom, 19 | ESConveyorEffectParallax10, 20 | ESConveyorEffectParallax20, 21 | ESConveyorEffectParallax33, 22 | ESConveyorEffectParallax40, 23 | ESConveyorEffectParallax50, 24 | ESConveyorEffectParallax150, 25 | ESConveyorEffectParallax200 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /Classes/ESConveyorBeltAttributes.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | 7 | #import 8 | 9 | @class ESConveyorElement; 10 | 11 | 12 | @interface ESConveyorBeltAttributes : UICollectionViewLayoutAttributes 13 | @property(nonatomic, strong) ESConveyorElement *element; 14 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorBeltAttributes.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorBeltAttributes.h" 7 | #import "ESConveyorElement.h" 8 | 9 | 10 | @implementation ESConveyorBeltAttributes 11 | { 12 | 13 | } 14 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorController.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class ESConveyorAdapter; 9 | 10 | 11 | @interface ESConveyorController : UICollectionViewController 12 | @property(nonatomic, strong) ESConveyorAdapter *adapter; 13 | 14 | - (id)initWithPages:(NSInteger)numberOfPages elements:(NSArray *)elements; 15 | 16 | - (void)scrollToNextPage; 17 | 18 | - (void)scrollToPage:(NSInteger)page animated:(BOOL)animated; 19 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorController.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorController.h" 7 | #import "ESConveyorFlowLayout.h" 8 | #import "ESConveyorAdapter.h" 9 | #import "ESConveyorElement.h" 10 | 11 | 12 | @implementation ESConveyorController 13 | { 14 | 15 | } 16 | - (instancetype)initWithPages:(NSInteger)numberOfPages elements:(NSArray *)elements 17 | { 18 | ESConveyorFlowLayout *layout = [[ESConveyorFlowLayout alloc] init]; 19 | 20 | self = [super initWithCollectionViewLayout:layout]; 21 | if (self) { 22 | 23 | self.adapter = [[ESConveyorAdapter alloc] initWithCollectionView:self.collectionView numberOfPages:numberOfPages elements:elements]; 24 | layout.adapter = self.adapter; 25 | 26 | self.collectionView.showsHorizontalScrollIndicator = NO; 27 | self.collectionView.showsVerticalScrollIndicator = NO; 28 | self.collectionView.backgroundColor = [UIColor whiteColor]; 29 | } 30 | 31 | return self; 32 | } 33 | 34 | 35 | - (void)scrollToNextPage 36 | { 37 | [self scrollToPage:(int)self.currentScrollPage + 1 animated:YES]; 38 | } 39 | 40 | - (NSInteger)currentScrollPage 41 | { 42 | return (NSInteger) roundf(self.collectionView.contentOffset.x/self.collectionView.bounds.size.width); 43 | } 44 | 45 | - (void)scrollToPage:(NSInteger)page animated:(BOOL)animated 46 | { 47 | NSIndexPath *path = [NSIndexPath indexPathForItem:0 inSection:page]; 48 | [self.collectionView scrollToItemAtIndexPath:path atScrollPosition:UICollectionViewScrollPositionLeft animated:animated]; 49 | } 50 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorEffects.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class ESConveyorElement; 9 | 10 | 11 | @interface ESConveyorEffects : NSObject 12 | 13 | - (UICollectionViewLayoutAttributes *)getAttributesForPage:(NSUInteger)page atOffset:(CGPoint)offset pageWidth:(CGSize)pageSize index:(NSUInteger)index progress:(CGFloat)progress element:(ESConveyorElement *)element; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/ESConveyorEffects.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorEffects.h" 7 | #import "ESConveyorBelt.h" 8 | #import "ESConveyorElement.h" 9 | #import "ESConveyorBeltAttributes.h" 10 | 11 | 12 | @implementation ESConveyorEffects 13 | { 14 | 15 | } 16 | 17 | - (UICollectionViewLayoutAttributes *)getAttributesForPage:(NSUInteger)page atOffset:(CGPoint)offset pageWidth:(CGSize)pageSize index:(NSUInteger)index progress:(CGFloat)progress element:(ESConveyorElement *)element 18 | { 19 | ESConveyorBeltAttributes *attr = [ESConveyorBeltAttributes layoutAttributesForSupplementaryViewOfKind:ESConveyorElementKind withIndexPath:[NSIndexPath indexPathForItem:(NSInteger) index inSection:0]]; 20 | attr.center = CGPointMake(offset.x + element.center.x, offset.y + element.center.y); 21 | attr.element = element; 22 | attr.size = element.size; 23 | attr.alpha = 1; 24 | 25 | NSArray *effects; 26 | BOOL exitingPage = offset.x > page * pageSize.width; 27 | BOOL exitingPreviousPage = offset.x > page-1 * pageSize.width; 28 | 29 | BOOL exiting = NO; 30 | 31 | if (page==element.inPage && !exitingPage) 32 | effects = element.inEffects; 33 | 34 | else if (page-1==element.outPage && exitingPreviousPage) 35 | { 36 | effects = element.outEffects; 37 | progress = 1 - progress; 38 | exiting = YES; 39 | page = page -1; 40 | } 41 | else 42 | effects = element.paginationEffects; 43 | 44 | if (effects==nil) 45 | return attr; 46 | 47 | if ([effects containsObject:@(ESConveyorEffectParallax10)]) 48 | [self doParallax:page pageSize:pageSize progress:progress attr:attr ratio:10 direction:exiting element:element]; 49 | 50 | if ([effects containsObject:@(ESConveyorEffectParallax20)]) 51 | [self doParallax:page pageSize:pageSize progress:progress attr:attr ratio:5 direction:exiting element:element]; 52 | 53 | if ([effects containsObject:@(ESConveyorEffectParallax33)]) 54 | [self doParallax:page pageSize:pageSize progress:progress attr:attr ratio:3.3 direction:exiting element:element]; 55 | 56 | if ([effects containsObject:@(ESConveyorEffectParallax40)]) 57 | [self doParallax:page pageSize:pageSize progress:progress attr:attr ratio:2.5 direction:exiting element:element]; 58 | 59 | if ([effects containsObject:@(ESConveyorEffectParallax50)]) 60 | [self doParallax:page pageSize:pageSize progress:progress attr:attr ratio:2 direction:exiting element:element]; 61 | 62 | if ([effects containsObject:@(ESConveyorEffectParallax150)]) 63 | [self doParallax:page pageSize:pageSize progress:progress attr:attr ratio:0.75 direction:exiting element:element]; 64 | 65 | if ([effects containsObject:@(ESConveyorEffectParallax200)]) 66 | [self doParallax:page pageSize:pageSize progress:progress attr:attr ratio:0.5 direction:exiting element:element]; 67 | 68 | if ([effects containsObject:@(ESConveyorEffectFade)]) 69 | { 70 | attr.alpha = progress; 71 | } 72 | 73 | if ([effects containsObject:@(ESConveyorEffectEdgeTop)]) 74 | { 75 | CGFloat start = - element.size.height / 2; 76 | CGFloat current = offset.y + ((element.center.y - start) * progress) + start; 77 | CGPoint newCenter = attr.center; 78 | newCenter.y = current; 79 | attr.center = newCenter; 80 | } 81 | 82 | if ([effects containsObject:@(ESConveyorEffectEdgeLeft)]) 83 | { 84 | CGFloat start = - (element.size.width / 2); 85 | CGFloat current = ((element.center.x - start) * progress) + start; 86 | CGPoint newCenter = attr.center; 87 | newCenter.x = offset.x +current; 88 | attr.center = newCenter; 89 | } 90 | 91 | if ([effects containsObject:@(ESConveyorEffectEdgeRight)]) 92 | { 93 | CGFloat start = pageSize.width + (element.size.width / 2); 94 | CGFloat current = ((element.center.x - start) * progress) + start; 95 | CGPoint newCenter = attr.center; 96 | newCenter.x = offset.x +current; 97 | attr.center = newCenter; 98 | } 99 | 100 | if ([effects containsObject:@(ESConveyorEffectEdgeBottom)]) 101 | { 102 | CGFloat start = pageSize.height + (element.size.height / 2); 103 | CGFloat current = ((element.center.y - start) * progress) + start; 104 | CGPoint newCenter = attr.center; 105 | newCenter.y = offset.y + current; 106 | attr.center = newCenter; 107 | } 108 | 109 | return attr; 110 | } 111 | 112 | 113 | - (void)doParallax:(NSUInteger)page pageSize:(CGSize)pageSize progress:(CGFloat)progress attr:(UICollectionViewLayoutAttributes *)attr ratio:(CGFloat)speed direction:(BOOL)exiting element:(ESConveyorElement *)element 114 | { 115 | CGFloat pixelsPerPage = pageSize.width / speed; 116 | CGFloat pixelsToMove = ((NSInteger)page - element.inPage) * pixelsPerPage; 117 | pixelsToMove = pixelsToMove - ( (pixelsPerPage * (1-progress)) * (exiting ? -1 : 1 )); 118 | 119 | CGPoint newCenter = attr.center; 120 | newCenter.x = newCenter.x - pixelsToMove; 121 | attr.center = newCenter; 122 | } 123 | 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /Classes/ESConveyorElement.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | extern NSString *const ESConveyorElementKind; 10 | 11 | @interface ESConveyorElement : NSObject 12 | 13 | @property(nonatomic) CGSize size; 14 | @property(nonatomic) CGPoint center; 15 | @property(nonatomic, strong) UIColor *color; 16 | @property(nonatomic, strong) UIView *view; 17 | 18 | @property(nonatomic, strong) NSArray *inEffects; 19 | @property(nonatomic, strong) NSArray *outEffects; 20 | 21 | @property(nonatomic) NSInteger inPage; 22 | @property(nonatomic) NSInteger outPage; 23 | 24 | 25 | @property(nonatomic, strong) NSArray *paginationEffects; 26 | 27 | + (ESConveyorElement *)elementForImageNamed:(NSString *)string; 28 | + (ESConveyorElement *)elementForImageNamed:(NSString *)imageName center:(CGPoint)center; 29 | 30 | + (ESConveyorElement *)elementForImage:(UIImage *)image center:(CGPoint)center; 31 | 32 | + (ESConveyorElement *)elementForView:(UIView *)view center:(CGPoint)center; 33 | 34 | + (ESConveyorElement *)elementForButtonOfClass:(Class)pClass title:(NSString *)title target:(id)target action:(SEL)action center:(CGPoint)center; 35 | + (ESConveyorElement *)elementForLabelOfClass:(Class)pClass text:(NSString *)text center:(CGPoint)center size:(CGSize)size; 36 | 37 | - (void)setEffects:(NSArray *)effects; 38 | 39 | - (void)setInEffects:(NSArray *)inEffects outEffects:(NSArray *)effects; 40 | - (void)setPage:(NSInteger)page; 41 | 42 | - (void)updateForPage:(NSUInteger)page totalPages:(NSInteger)pages progress:(CGFloat)progress offset:(CGPoint)offset; 43 | 44 | - (BOOL)isVisibleInPage:(NSUInteger)page; 45 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorElement.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorElement.h" 7 | #import "ESConveyorBelt.h" 8 | 9 | NSString *const ESConveyorElementKind = @"ESConveyorElement"; 10 | 11 | @implementation ESConveyorElement 12 | { 13 | 14 | } 15 | 16 | + (ESConveyorElement *)elementForImageNamed:(NSString *)imageName center:(CGPoint)center 17 | { 18 | ESConveyorElement *result = [ESConveyorElement new]; 19 | UIImage *image = [UIImage imageNamed:imageName]; 20 | result.view = [[UIImageView alloc] initWithImage:image]; 21 | result.center = center; 22 | result.size = image.size; 23 | result.color = [UIColor clearColor]; 24 | return result; 25 | } 26 | 27 | 28 | + (ESConveyorElement *)elementForImage:(UIImage *)image center:(CGPoint)center 29 | { 30 | ESConveyorElement *result = [ESConveyorElement new]; 31 | result.view = [[UIImageView alloc] initWithImage:image]; 32 | result.center = center; 33 | result.size = image.size; 34 | result.color = [UIColor clearColor]; 35 | return result; 36 | } 37 | 38 | + (ESConveyorElement *)elementForView:(UIView *)view center:(CGPoint)center 39 | { 40 | ESConveyorElement *result = [ESConveyorElement new]; 41 | result.view = view; 42 | result.center = center; 43 | result.size = view.frame.size; 44 | result.color = [UIColor clearColor]; 45 | return result; 46 | } 47 | 48 | + (ESConveyorElement *)elementForButtonOfClass:(Class)pClass title:(NSString *)title target:(id)target action:(SEL)action center:(CGPoint)center 49 | { 50 | ESConveyorElement *result = [ESConveyorElement new]; 51 | 52 | UIButton *button = [pClass new]; 53 | [button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; 54 | result.view = button; 55 | result.center = center; 56 | [button setTitle:title forState:UIControlStateNormal]; 57 | [button sizeToFit]; 58 | result.size = button.frame.size; 59 | return result; 60 | } 61 | 62 | - (void)setSize:(CGSize)size 63 | { 64 | _size = size; 65 | self.view.frame = CGRectMake(0, 0, size.width, size.height); 66 | } 67 | 68 | 69 | + (ESConveyorElement *)elementForLabelOfClass:(Class)pClass text:(NSString *)text center:(CGPoint)center size:(CGSize)size 70 | { 71 | ESConveyorElement *result = [ESConveyorElement new]; 72 | 73 | UILabel *label = [pClass new]; 74 | label.frame = CGRectMake(0, 0, size.width, size.height); 75 | result.view = label; 76 | result.center = center; 77 | result.size = size; 78 | label.backgroundColor = [UIColor clearColor]; 79 | label.text = text; 80 | return result; 81 | } 82 | 83 | - (void)setEffects:(NSArray *)effects 84 | { 85 | [self setInEffects:effects outEffects:effects]; 86 | 87 | } 88 | - (void)setInEffects:(NSArray *)inEffects outEffects:(NSArray *)effects 89 | { 90 | self.inEffects = inEffects; 91 | self.outEffects = effects; 92 | } 93 | 94 | + (ESConveyorElement *)elementForImageNamed:(NSString *)string 95 | { 96 | ESConveyorElement *element = [self elementForImageNamed:string center:CGPointZero]; 97 | UIImageView *imageView = (UIImageView *) element.view; 98 | element.center = CGPointMake(imageView.image.size.width / 2 , imageView.image.size.height / 2); 99 | return element; 100 | } 101 | 102 | - (void)setPage:(NSInteger)page 103 | { 104 | self.inPage = page; 105 | self.outPage = page; 106 | } 107 | 108 | - (void)updateForPage:(NSUInteger)page totalPages:(NSInteger)pages progress:(CGFloat)progress offset:(CGPoint)offset 109 | { 110 | // do nothing 111 | } 112 | 113 | - (BOOL)isVisibleInPage:(NSUInteger)page 114 | { 115 | return page >= self.inPage && page <= self.outPage + 1; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /Classes/ESConveyorFlowLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class ESConveyorElement; 9 | @class ESConveyorAdapter; 10 | @class EZConveyorEffects; 11 | 12 | 13 | @interface ESConveyorFlowLayout : UICollectionViewFlowLayout 14 | 15 | 16 | @property(nonatomic, weak) ESConveyorAdapter *adapter; 17 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorFlowLayout.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorFlowLayout.h" 7 | #import "ESConveyorElement.h" 8 | #import "ESConveyorBelt.h" 9 | #import "ESConveyorAdapter.h" 10 | #import "ESConveyorEffects.h" 11 | 12 | 13 | @interface ESConveyorFlowLayout () 14 | @property(nonatomic, strong) NSMutableSet *processedElements; 15 | @property(nonatomic, strong) ESConveyorEffects *effects; 16 | @end 17 | 18 | @implementation ESConveyorFlowLayout 19 | { 20 | 21 | } 22 | 23 | - (id)init 24 | { 25 | self = [super init]; 26 | if (self) { 27 | self.scrollDirection = UICollectionViewScrollDirectionHorizontal; 28 | self.effects = [ESConveyorEffects new]; 29 | } 30 | 31 | return self; 32 | } 33 | 34 | - (void)prepareLayout 35 | { 36 | [super prepareLayout]; 37 | 38 | self.itemSize = self.collectionView.frame.size; 39 | self.minimumInteritemSpacing = 0; 40 | self.minimumLineSpacing = 0; 41 | } 42 | 43 | - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 44 | { 45 | NSArray *items = [super layoutAttributesForElementsInRect:rect]; 46 | 47 | items = [items arrayByAddingObjectsFromArray:[self createDecorationItems]]; 48 | return items; 49 | } 50 | 51 | - (NSArray *)createDecorationItems 52 | { 53 | self.processedElements = [NSMutableSet new]; 54 | NSMutableArray *items = [NSMutableArray new]; 55 | CGPoint offset = self.collectionView.contentOffset; 56 | 57 | [self createDecorationItems:items page:(NSUInteger) self.nextPage offset:offset elements:[self.adapter elements]]; 58 | 59 | self.processedElements = nil; 60 | return items; 61 | } 62 | 63 | - (void)createDecorationItems:(NSMutableArray *)items page:(NSUInteger)page offset:(CGPoint)offset elements:(NSArray *)elements 64 | { 65 | NSInteger zIndex = 0; 66 | for (ESConveyorElement *element in elements) 67 | { 68 | CGFloat progress = [self pageTransitionProgressForPage:page]; 69 | 70 | BOOL showItem = [element isVisibleInPage:page]; 71 | if (!showItem) 72 | continue; 73 | 74 | [element updateForPage:page totalPages:self.adapter.numberOfPages progress:progress offset:offset]; 75 | 76 | UICollectionViewLayoutAttributes *attr= [self.effects getAttributesForPage:page 77 | atOffset:offset 78 | pageWidth:self.collectionView.frame.size 79 | index:[elements indexOfObject:element] 80 | progress:progress 81 | element:element]; 82 | attr.zIndex = (NSInteger)zIndex+1; 83 | [items addObject:attr]; 84 | 85 | zIndex ++; 86 | 87 | } 88 | } 89 | - (CGFloat)pageTransitionProgressForPage:(NSUInteger)page 90 | { 91 | CGFloat finalPoint = self.collectionView.frame.size.width * page; 92 | CGFloat result = ((int)self.collectionView.contentOffset.x - finalPoint)/ self.collectionView.frame.size.width; 93 | return 1 - (result < 0 ? - result : result > 1 ? 1 : result); 94 | } 95 | 96 | - (NSInteger)previousPage 97 | { 98 | return (NSInteger) (self.collectionView.contentOffset.x / self.collectionView.frame.size.width); 99 | } 100 | 101 | - (NSInteger)nextPage 102 | { 103 | return (NSInteger) ceil((self.collectionView.contentOffset.x / self.collectionView.frame.size.width)); 104 | } 105 | 106 | - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds 107 | { 108 | return YES; 109 | } 110 | 111 | - (void)prepareForAnimatedBoundsChange:(CGRect)oldBounds 112 | { 113 | [super prepareForAnimatedBoundsChange:oldBounds]; 114 | 115 | if( !CGRectEqualToRect( self.collectionView.bounds, oldBounds ) ) 116 | { 117 | [self invalidateLayout]; 118 | } 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /Classes/ESConveyorPageCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface ESConveyorPageCell : UICollectionViewCell 10 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorPageCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | 7 | #import "ESConveyorPageCell.h" 8 | 9 | 10 | @implementation ESConveyorPageCell 11 | { 12 | 13 | } 14 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorPageControlElement.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | 7 | #import 8 | #import "ESConveyorElement.h" 9 | 10 | 11 | @interface ESConveyorPageControlElement : ESConveyorElement 12 | 13 | @property(nonatomic, strong) UIPageControl *pageControl; 14 | 15 | - (id)initWithClass:(Class)pClass center:(CGPoint)center; 16 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorPageControlElement.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorPageControlElement.h" 7 | 8 | 9 | @interface ESConveyorPageControlElement () 10 | 11 | @end 12 | 13 | @implementation ESConveyorPageControlElement 14 | { 15 | 16 | } 17 | - (id)initWithClass:(Class)pClass center:(CGPoint)center 18 | { 19 | if (self = [super init]) 20 | { 21 | self.center = center; 22 | self.size = CGSizeMake(900, 44); 23 | 24 | self.pageControl = (UIPageControl *) [pClass new]; 25 | self.pageControl.frame = CGRectMake(0, 0, self.size.width, self.size.height); 26 | self.pageControl.numberOfPages = 10; 27 | self.pageControl.currentPage = 1; 28 | self.view = self.pageControl; 29 | 30 | } 31 | return self; 32 | } 33 | 34 | - (void)updateForPage:(NSUInteger)page totalPages:(NSInteger)numberOfPages progress:(CGFloat)progress offset:(CGPoint)offset 35 | { 36 | [super updateForPage:page totalPages:numberOfPages progress:progress offset:offset]; 37 | 38 | NSUInteger newPage = progress > 0.5f? page : page - 1; 39 | self.pageControl.currentPage = newPage <= 0 ? 0 : (NSInteger)newPage; 40 | self.pageControl.numberOfPages = numberOfPages; 41 | } 42 | 43 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorView.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class ESConveyorElement; 9 | 10 | 11 | @interface ESConveyorView : UICollectionReusableView 12 | 13 | @end -------------------------------------------------------------------------------- /Classes/ESConveyorView.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 6/8/13. 3 | // Copyright (c) 2013 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorView.h" 7 | #import "ESConveyorElement.h" 8 | #import "ESConveyorBeltAttributes.h" 9 | 10 | 11 | @interface ESConveyorView () 12 | @end 13 | 14 | @implementation ESConveyorView 15 | { 16 | 17 | } 18 | 19 | - (void)setCurrentView:(UIView *)currentView 20 | { 21 | for (UIView *view in self.subviews) 22 | [view removeFromSuperview]; 23 | 24 | [self addSubview:currentView]; 25 | [self setNeedsLayout]; 26 | } 27 | 28 | - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes 29 | { 30 | ESConveyorBeltAttributes *attrs = (ESConveyorBeltAttributes *) layoutAttributes; 31 | [super applyLayoutAttributes:layoutAttributes]; 32 | self.currentView = attrs.element.view; 33 | } 34 | 35 | @end -------------------------------------------------------------------------------- /ESConveyorBelt.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/ESConveyorBelt.gif -------------------------------------------------------------------------------- /ESConveyorBelt.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "ESConveyorBelt" 3 | s.version = "1.0.0" 4 | s.summary = "Create nice tutorial pages with parallax and animations with ease" 5 | s.description = <<-DESC 6 | ESConveyorBelt is a UICollectionView subclass that allows you to 7 | create simple tutorial screen with animations for elements presented. 8 | 9 | More info to come. 10 | 11 | DESC 12 | s.homepage = "https://github.com/escoz/ESConveyorBelt/" 13 | s.license = 'MIT' 14 | s.author = { "Eduardo Scoz" => "eduardoscoz@gmail.com" } 15 | s.source = { :git => "https://github.com/escoz/ESConveyorBelt.git", :tag => s.version.to_s } 16 | s.social_media_url = 'https://twitter.com/escoz' 17 | 18 | s.platform = :ios, '7.0' 19 | s.ios.deployment_target = '7.0' 20 | s.requires_arc = true 21 | 22 | s.source_files = 'Classes' 23 | 24 | s.public_header_files = 'Classes/**/*.h' 25 | s.frameworks = 'UIKit', 'Foundation' 26 | end 27 | -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5C50E0C15CF437AA9A5F2D8F /* flip_flops@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5C50E08CD070481394CAA3B5 /* flip_flops@2x.png */; }; 11 | 5C50E196610A747067C9AED5 /* beach_chair@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5C50E41F1FCB99687E967667 /* beach_chair@2x.png */; }; 12 | 5C50E31470AC4568B3AB3527 /* beach_bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 5C50E3D324854CB55A700834 /* beach_bg.png */; }; 13 | 5C50E3725B462F4ED683BF46 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C50E3A2A0558BCFA385E131 /* main.m */; }; 14 | 5C50E3A50DDE10A43DB415FD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C50E6F91BE5430E77323697 /* Foundation.framework */; }; 15 | 5C50E4A75EA965F8058E5651 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C50EA631A7006F9EE665926 /* UIKit.framework */; }; 16 | 5C50E4B83D70025E0520721D /* surfboard@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5C50E3A69CB1BBC0F546B0B0 /* surfboard@2x.png */; }; 17 | 5C50E52AC29FEE239B3D3195 /* cocktail@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5C50EA4406E260D61CB14826 /* cocktail@2x.png */; }; 18 | 5C50E56EEAA2F86B3ECCFC53 /* flippers@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5C50E549A40F2E0F0BC75577 /* flippers@2x.png */; }; 19 | 5C50E7DD22A806FDD18B9B28 /* ESAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C50EA4FDB99C0A04393C187 /* ESAppDelegate.m */; }; 20 | 5C50E8DA0843E5753A394A78 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5C50ECFD4B69B4888B56780F /* Images.xcassets */; }; 21 | 5C50E9032ECFA7A858B7A6CA /* umbrella@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5C50E1D813238E94ED9CCA55 /* umbrella@2x.png */; }; 22 | 5C50E9D027B9301093289645 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C50E861AB62C806831EC832 /* CoreGraphics.framework */; }; 23 | 5C50EAB26898A9B50D104EB3 /* goldengate@2x.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 5C50EEE2F4E2C5A6F63B4566 /* goldengate@2x.jpg */; }; 24 | 5C50EB8EE309B5C2B82132C7 /* bacon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5C50E6E2CC543456CC0011A5 /* bacon@2x.png */; }; 25 | 5C50EFCA4A224E244BB725A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5C50E8D24FC729943FB5C7E9 /* InfoPlist.strings */; }; 26 | 934784B31933D13800E02A72 /* ESConveyorAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784A11933D13800E02A72 /* ESConveyorAdapter.m */; }; 27 | 934784B41933D13800E02A72 /* ESConveyorBeltAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784A41933D13800E02A72 /* ESConveyorBeltAttributes.m */; }; 28 | 934784B51933D13800E02A72 /* ESConveyorController.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784A61933D13800E02A72 /* ESConveyorController.m */; }; 29 | 934784B61933D13800E02A72 /* ESConveyorEffects.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784A81933D13800E02A72 /* ESConveyorEffects.m */; }; 30 | 934784B71933D13800E02A72 /* ESConveyorElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784AA1933D13800E02A72 /* ESConveyorElement.m */; }; 31 | 934784B81933D13800E02A72 /* ESConveyorFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784AC1933D13800E02A72 /* ESConveyorFlowLayout.m */; }; 32 | 934784B91933D13800E02A72 /* ESConveyorPageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784AE1933D13800E02A72 /* ESConveyorPageCell.m */; }; 33 | 934784BA1933D13800E02A72 /* ESConveyorPageControlElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784B01933D13800E02A72 /* ESConveyorPageControlElement.m */; }; 34 | 934784BB1933D13800E02A72 /* ESConveyorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 934784B21933D13800E02A72 /* ESConveyorView.m */; }; 35 | D813CF5C19282F3600DC2A9B /* ESConveyorSample1Builder.m in Sources */ = {isa = PBXBuildFile; fileRef = D813CF5719282F3600DC2A9B /* ESConveyorSample1Builder.m */; }; 36 | D813CF5D19282F3600DC2A9B /* ESConveyorSample2Builder.m in Sources */ = {isa = PBXBuildFile; fileRef = D813CF5919282F3600DC2A9B /* ESConveyorSample2Builder.m */; }; 37 | D813CF5E19282F3600DC2A9B /* ESConveyorSampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D813CF5B19282F3600DC2A9B /* ESConveyorSampleViewController.m */; }; 38 | /* End PBXBuildFile section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 5C50E08CD070481394CAA3B5 /* flip_flops@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "flip_flops@2x.png"; sourceTree = ""; }; 42 | 5C50E1D813238E94ED9CCA55 /* umbrella@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "umbrella@2x.png"; sourceTree = ""; }; 43 | 5C50E3A2A0558BCFA385E131 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 44 | 5C50E3A69CB1BBC0F546B0B0 /* surfboard@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "surfboard@2x.png"; sourceTree = ""; }; 45 | 5C50E3D324854CB55A700834 /* beach_bg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = beach_bg.png; sourceTree = ""; }; 46 | 5C50E41F1FCB99687E967667 /* beach_chair@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "beach_chair@2x.png"; sourceTree = ""; }; 47 | 5C50E549A40F2E0F0BC75577 /* flippers@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "flippers@2x.png"; sourceTree = ""; }; 48 | 5C50E65DADFD98E16DBAA335 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 49 | 5C50E6E2CC543456CC0011A5 /* bacon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bacon@2x.png"; sourceTree = ""; }; 50 | 5C50E6F91BE5430E77323697 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 51 | 5C50E723FD6C2C003B350647 /* ESConveyorBeltSample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ESConveyorBeltSample-Prefix.pch"; sourceTree = ""; }; 52 | 5C50E861AB62C806831EC832 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 53 | 5C50E8F9077BADEC298B4E11 /* ESAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ESAppDelegate.h; sourceTree = ""; }; 54 | 5C50EA4406E260D61CB14826 /* cocktail@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cocktail@2x.png"; sourceTree = ""; }; 55 | 5C50EA4FDB99C0A04393C187 /* ESAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ESAppDelegate.m; sourceTree = ""; }; 56 | 5C50EA631A7006F9EE665926 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 57 | 5C50ECFD4B69B4888B56780F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 58 | 5C50ED813768FE7022AA4E8C /* ESConveyorBeltSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ESConveyorBeltSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 5C50EE81817E3B23B30CB063 /* ESConveyorBeltSample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.info; path = "ESConveyorBeltSample-Info.plist"; sourceTree = ""; }; 60 | 5C50EEE2F4E2C5A6F63B4566 /* goldengate@2x.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "goldengate@2x.jpg"; sourceTree = ""; }; 61 | 934784A01933D13800E02A72 /* ESConveyorAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorAdapter.h; sourceTree = ""; }; 62 | 934784A11933D13800E02A72 /* ESConveyorAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorAdapter.m; sourceTree = ""; }; 63 | 934784A21933D13800E02A72 /* ESConveyorBelt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorBelt.h; sourceTree = ""; }; 64 | 934784A31933D13800E02A72 /* ESConveyorBeltAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorBeltAttributes.h; sourceTree = ""; }; 65 | 934784A41933D13800E02A72 /* ESConveyorBeltAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorBeltAttributes.m; sourceTree = ""; }; 66 | 934784A51933D13800E02A72 /* ESConveyorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorController.h; sourceTree = ""; }; 67 | 934784A61933D13800E02A72 /* ESConveyorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorController.m; sourceTree = ""; }; 68 | 934784A71933D13800E02A72 /* ESConveyorEffects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorEffects.h; sourceTree = ""; }; 69 | 934784A81933D13800E02A72 /* ESConveyorEffects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorEffects.m; sourceTree = ""; }; 70 | 934784A91933D13800E02A72 /* ESConveyorElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorElement.h; sourceTree = ""; }; 71 | 934784AA1933D13800E02A72 /* ESConveyorElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorElement.m; sourceTree = ""; }; 72 | 934784AB1933D13800E02A72 /* ESConveyorFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorFlowLayout.h; sourceTree = ""; }; 73 | 934784AC1933D13800E02A72 /* ESConveyorFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorFlowLayout.m; sourceTree = ""; }; 74 | 934784AD1933D13800E02A72 /* ESConveyorPageCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorPageCell.h; sourceTree = ""; }; 75 | 934784AE1933D13800E02A72 /* ESConveyorPageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorPageCell.m; sourceTree = ""; }; 76 | 934784AF1933D13800E02A72 /* ESConveyorPageControlElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorPageControlElement.h; sourceTree = ""; }; 77 | 934784B01933D13800E02A72 /* ESConveyorPageControlElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorPageControlElement.m; sourceTree = ""; }; 78 | 934784B11933D13800E02A72 /* ESConveyorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorView.h; sourceTree = ""; }; 79 | 934784B21933D13800E02A72 /* ESConveyorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorView.m; sourceTree = ""; }; 80 | D813CF5619282F3600DC2A9B /* ESConveyorSample1Builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorSample1Builder.h; sourceTree = ""; }; 81 | D813CF5719282F3600DC2A9B /* ESConveyorSample1Builder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorSample1Builder.m; sourceTree = ""; }; 82 | D813CF5819282F3600DC2A9B /* ESConveyorSample2Builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorSample2Builder.h; sourceTree = ""; }; 83 | D813CF5919282F3600DC2A9B /* ESConveyorSample2Builder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorSample2Builder.m; sourceTree = ""; }; 84 | D813CF5A19282F3600DC2A9B /* ESConveyorSampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ESConveyorSampleViewController.h; sourceTree = ""; }; 85 | D813CF5B19282F3600DC2A9B /* ESConveyorSampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ESConveyorSampleViewController.m; sourceTree = ""; }; 86 | /* End PBXFileReference section */ 87 | 88 | /* Begin PBXFrameworksBuildPhase section */ 89 | 5C50E5B4654B7BA0CAA6F82C /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | 5C50E3A50DDE10A43DB415FD /* Foundation.framework in Frameworks */, 94 | 5C50E9D027B9301093289645 /* CoreGraphics.framework in Frameworks */, 95 | 5C50E4A75EA965F8058E5651 /* UIKit.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | /* End PBXFrameworksBuildPhase section */ 100 | 101 | /* Begin PBXGroup section */ 102 | 5C50E402CC7456173CFF79FE /* Supporting Files */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 5C50EE81817E3B23B30CB063 /* ESConveyorBeltSample-Info.plist */, 106 | 5C50E8D24FC729943FB5C7E9 /* InfoPlist.strings */, 107 | 5C50E3A2A0558BCFA385E131 /* main.m */, 108 | 5C50E723FD6C2C003B350647 /* ESConveyorBeltSample-Prefix.pch */, 109 | ); 110 | name = "Supporting Files"; 111 | sourceTree = ""; 112 | }; 113 | 5C50E7C84928FAA5E4533359 /* Products */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 5C50ED813768FE7022AA4E8C /* ESConveyorBeltSample.app */, 117 | ); 118 | name = Products; 119 | sourceTree = ""; 120 | }; 121 | 5C50EA49F65000E390192ADC /* Frameworks */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 5C50E6F91BE5430E77323697 /* Foundation.framework */, 125 | 5C50E861AB62C806831EC832 /* CoreGraphics.framework */, 126 | 5C50EA631A7006F9EE665926 /* UIKit.framework */, 127 | ); 128 | name = Frameworks; 129 | sourceTree = ""; 130 | }; 131 | 5C50EB15AB9524975ED7CA15 /* Classes */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 934784A01933D13800E02A72 /* ESConveyorAdapter.h */, 135 | 934784A11933D13800E02A72 /* ESConveyorAdapter.m */, 136 | 934784A21933D13800E02A72 /* ESConveyorBelt.h */, 137 | 934784A31933D13800E02A72 /* ESConveyorBeltAttributes.h */, 138 | 934784A41933D13800E02A72 /* ESConveyorBeltAttributes.m */, 139 | 934784A51933D13800E02A72 /* ESConveyorController.h */, 140 | 934784A61933D13800E02A72 /* ESConveyorController.m */, 141 | 934784A71933D13800E02A72 /* ESConveyorEffects.h */, 142 | 934784A81933D13800E02A72 /* ESConveyorEffects.m */, 143 | 934784A91933D13800E02A72 /* ESConveyorElement.h */, 144 | 934784AA1933D13800E02A72 /* ESConveyorElement.m */, 145 | 934784AB1933D13800E02A72 /* ESConveyorFlowLayout.h */, 146 | 934784AC1933D13800E02A72 /* ESConveyorFlowLayout.m */, 147 | 934784AD1933D13800E02A72 /* ESConveyorPageCell.h */, 148 | 934784AE1933D13800E02A72 /* ESConveyorPageCell.m */, 149 | 934784AF1933D13800E02A72 /* ESConveyorPageControlElement.h */, 150 | 934784B01933D13800E02A72 /* ESConveyorPageControlElement.m */, 151 | 934784B11933D13800E02A72 /* ESConveyorView.h */, 152 | 934784B21933D13800E02A72 /* ESConveyorView.m */, 153 | ); 154 | name = Classes; 155 | path = ../Classes; 156 | sourceTree = ""; 157 | }; 158 | 5C50EB56D777807589C813EB /* ESConveyorBeltSample */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | D813CF5619282F3600DC2A9B /* ESConveyorSample1Builder.h */, 162 | D813CF5719282F3600DC2A9B /* ESConveyorSample1Builder.m */, 163 | D813CF5819282F3600DC2A9B /* ESConveyorSample2Builder.h */, 164 | D813CF5919282F3600DC2A9B /* ESConveyorSample2Builder.m */, 165 | D813CF5A19282F3600DC2A9B /* ESConveyorSampleViewController.h */, 166 | D813CF5B19282F3600DC2A9B /* ESConveyorSampleViewController.m */, 167 | 5C50E402CC7456173CFF79FE /* Supporting Files */, 168 | 5C50E8F9077BADEC298B4E11 /* ESAppDelegate.h */, 169 | 5C50EA4FDB99C0A04393C187 /* ESAppDelegate.m */, 170 | 5C50ECFD4B69B4888B56780F /* Images.xcassets */, 171 | 5C50EEBB69776D991F90C88C /* Resources */, 172 | ); 173 | path = ESConveyorBeltSample; 174 | sourceTree = ""; 175 | }; 176 | 5C50EE3122B2B4DAE93FAABE = { 177 | isa = PBXGroup; 178 | children = ( 179 | 5C50E7C84928FAA5E4533359 /* Products */, 180 | 5C50EA49F65000E390192ADC /* Frameworks */, 181 | 5C50EB56D777807589C813EB /* ESConveyorBeltSample */, 182 | 5C50EB15AB9524975ED7CA15 /* Classes */, 183 | ); 184 | sourceTree = ""; 185 | }; 186 | 5C50EEBB69776D991F90C88C /* Resources */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | 5C50E6E2CC543456CC0011A5 /* bacon@2x.png */, 190 | 5C50EA4406E260D61CB14826 /* cocktail@2x.png */, 191 | 5C50E549A40F2E0F0BC75577 /* flippers@2x.png */, 192 | 5C50E1D813238E94ED9CCA55 /* umbrella@2x.png */, 193 | 5C50E3A69CB1BBC0F546B0B0 /* surfboard@2x.png */, 194 | 5C50E08CD070481394CAA3B5 /* flip_flops@2x.png */, 195 | 5C50EEE2F4E2C5A6F63B4566 /* goldengate@2x.jpg */, 196 | 5C50E41F1FCB99687E967667 /* beach_chair@2x.png */, 197 | 5C50E3D324854CB55A700834 /* beach_bg.png */, 198 | ); 199 | path = Resources; 200 | sourceTree = ""; 201 | }; 202 | /* End PBXGroup section */ 203 | 204 | /* Begin PBXNativeTarget section */ 205 | 5C50E016236A45F011DB7DCB /* ESConveyorBeltSample */ = { 206 | isa = PBXNativeTarget; 207 | buildConfigurationList = 5C50ECDA781FD695130D2F0C /* Build configuration list for PBXNativeTarget "ESConveyorBeltSample" */; 208 | buildPhases = ( 209 | 5C50ECBF62C13A5CF4F87F41 /* Sources */, 210 | 5C50E5B4654B7BA0CAA6F82C /* Frameworks */, 211 | 5C50E36F563C8ADE0F17ECE7 /* Resources */, 212 | ); 213 | buildRules = ( 214 | ); 215 | dependencies = ( 216 | ); 217 | name = ESConveyorBeltSample; 218 | productName = ESConveyorBeltSample; 219 | productReference = 5C50ED813768FE7022AA4E8C /* ESConveyorBeltSample.app */; 220 | productType = "com.apple.product-type.application"; 221 | }; 222 | /* End PBXNativeTarget section */ 223 | 224 | /* Begin PBXProject section */ 225 | 5C50E605EDDEB34024C013C2 /* Project object */ = { 226 | isa = PBXProject; 227 | attributes = { 228 | ORGANIZATIONNAME = "ESCOZ inc"; 229 | }; 230 | buildConfigurationList = 5C50E8538C6442CA82FA7929 /* Build configuration list for PBXProject "ESConveyorBeltSample" */; 231 | compatibilityVersion = "Xcode 3.2"; 232 | developmentRegion = English; 233 | hasScannedForEncodings = 0; 234 | knownRegions = ( 235 | en, 236 | ); 237 | mainGroup = 5C50EE3122B2B4DAE93FAABE; 238 | productRefGroup = 5C50E7C84928FAA5E4533359 /* Products */; 239 | projectDirPath = ""; 240 | projectRoot = ""; 241 | targets = ( 242 | 5C50E016236A45F011DB7DCB /* ESConveyorBeltSample */, 243 | ); 244 | }; 245 | /* End PBXProject section */ 246 | 247 | /* Begin PBXResourcesBuildPhase section */ 248 | 5C50E36F563C8ADE0F17ECE7 /* Resources */ = { 249 | isa = PBXResourcesBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | 5C50EFCA4A224E244BB725A6 /* InfoPlist.strings in Resources */, 253 | 5C50E8DA0843E5753A394A78 /* Images.xcassets in Resources */, 254 | 5C50EB8EE309B5C2B82132C7 /* bacon@2x.png in Resources */, 255 | 5C50E52AC29FEE239B3D3195 /* cocktail@2x.png in Resources */, 256 | 5C50E56EEAA2F86B3ECCFC53 /* flippers@2x.png in Resources */, 257 | 5C50E9032ECFA7A858B7A6CA /* umbrella@2x.png in Resources */, 258 | 5C50E4B83D70025E0520721D /* surfboard@2x.png in Resources */, 259 | 5C50E0C15CF437AA9A5F2D8F /* flip_flops@2x.png in Resources */, 260 | 5C50EAB26898A9B50D104EB3 /* goldengate@2x.jpg in Resources */, 261 | 5C50E196610A747067C9AED5 /* beach_chair@2x.png in Resources */, 262 | 5C50E31470AC4568B3AB3527 /* beach_bg.png in Resources */, 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXResourcesBuildPhase section */ 267 | 268 | /* Begin PBXSourcesBuildPhase section */ 269 | 5C50ECBF62C13A5CF4F87F41 /* Sources */ = { 270 | isa = PBXSourcesBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | 5C50E3725B462F4ED683BF46 /* main.m in Sources */, 274 | D813CF5D19282F3600DC2A9B /* ESConveyorSample2Builder.m in Sources */, 275 | 934784B51933D13800E02A72 /* ESConveyorController.m in Sources */, 276 | 934784B71933D13800E02A72 /* ESConveyorElement.m in Sources */, 277 | 934784B41933D13800E02A72 /* ESConveyorBeltAttributes.m in Sources */, 278 | 934784BA1933D13800E02A72 /* ESConveyorPageControlElement.m in Sources */, 279 | 934784B61933D13800E02A72 /* ESConveyorEffects.m in Sources */, 280 | D813CF5E19282F3600DC2A9B /* ESConveyorSampleViewController.m in Sources */, 281 | 934784B81933D13800E02A72 /* ESConveyorFlowLayout.m in Sources */, 282 | 5C50E7DD22A806FDD18B9B28 /* ESAppDelegate.m in Sources */, 283 | 934784B91933D13800E02A72 /* ESConveyorPageCell.m in Sources */, 284 | 934784B31933D13800E02A72 /* ESConveyorAdapter.m in Sources */, 285 | D813CF5C19282F3600DC2A9B /* ESConveyorSample1Builder.m in Sources */, 286 | 934784BB1933D13800E02A72 /* ESConveyorView.m in Sources */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | /* End PBXSourcesBuildPhase section */ 291 | 292 | /* Begin PBXVariantGroup section */ 293 | 5C50E8D24FC729943FB5C7E9 /* InfoPlist.strings */ = { 294 | isa = PBXVariantGroup; 295 | children = ( 296 | 5C50E65DADFD98E16DBAA335 /* en */, 297 | ); 298 | name = InfoPlist.strings; 299 | sourceTree = ""; 300 | }; 301 | /* End PBXVariantGroup section */ 302 | 303 | /* Begin XCBuildConfiguration section */ 304 | 5C50E010171715B8EEBBB5FB /* Release */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | ALWAYS_SEARCH_USER_PATHS = NO; 308 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 309 | CLANG_CXX_LIBRARY = "libc++"; 310 | CLANG_ENABLE_MODULES = YES; 311 | CLANG_ENABLE_OBJC_ARC = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_CONSTANT_CONVERSION = YES; 314 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 315 | CLANG_WARN_EMPTY_BODY = YES; 316 | CLANG_WARN_ENUM_CONVERSION = YES; 317 | CLANG_WARN_INT_CONVERSION = YES; 318 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 319 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 320 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 321 | COPY_PHASE_STRIP = YES; 322 | ENABLE_NS_ASSERTIONS = NO; 323 | GCC_C_LANGUAGE_STANDARD = gnu99; 324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 326 | GCC_WARN_UNDECLARED_SELECTOR = YES; 327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 328 | GCC_WARN_UNUSED_FUNCTION = YES; 329 | GCC_WARN_UNUSED_VARIABLE = YES; 330 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 331 | SDKROOT = iphoneos; 332 | TARGETED_DEVICE_FAMILY = "1,2"; 333 | VALIDATE_PRODUCT = YES; 334 | }; 335 | name = Release; 336 | }; 337 | 5C50E0702759D8B3022B033E /* Debug */ = { 338 | isa = XCBuildConfiguration; 339 | buildSettings = { 340 | ALWAYS_SEARCH_USER_PATHS = NO; 341 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 342 | CLANG_CXX_LIBRARY = "libc++"; 343 | CLANG_ENABLE_MODULES = YES; 344 | CLANG_ENABLE_OBJC_ARC = YES; 345 | CLANG_WARN_BOOL_CONVERSION = YES; 346 | CLANG_WARN_CONSTANT_CONVERSION = YES; 347 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 348 | CLANG_WARN_EMPTY_BODY = YES; 349 | CLANG_WARN_ENUM_CONVERSION = YES; 350 | CLANG_WARN_INT_CONVERSION = YES; 351 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 352 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 353 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 354 | COPY_PHASE_STRIP = NO; 355 | GCC_C_LANGUAGE_STANDARD = gnu99; 356 | GCC_DYNAMIC_NO_PIC = NO; 357 | GCC_OPTIMIZATION_LEVEL = 0; 358 | GCC_PREPROCESSOR_DEFINITIONS = ( 359 | "DEBUG=1", 360 | "$(inherited)", 361 | ); 362 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 363 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 364 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 365 | GCC_WARN_UNDECLARED_SELECTOR = YES; 366 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 367 | GCC_WARN_UNUSED_FUNCTION = YES; 368 | GCC_WARN_UNUSED_VARIABLE = YES; 369 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 370 | ONLY_ACTIVE_ARCH = YES; 371 | SDKROOT = iphoneos; 372 | TARGETED_DEVICE_FAMILY = "1,2"; 373 | }; 374 | name = Debug; 375 | }; 376 | 5C50E9CB902A2748FDA348B0 /* Debug */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 380 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 381 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 382 | GCC_PREFIX_HEADER = "ESConveyorBeltSample/ESConveyorBeltSample-Prefix.pch"; 383 | INFOPLIST_FILE = "ESConveyorBeltSample/ESConveyorBeltSample-Info.plist"; 384 | PRODUCT_NAME = "$(TARGET_NAME)"; 385 | WRAPPER_EXTENSION = app; 386 | }; 387 | name = Debug; 388 | }; 389 | 5C50EA5E981AA3483DB25AF2 /* Release */ = { 390 | isa = XCBuildConfiguration; 391 | buildSettings = { 392 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 393 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 394 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 395 | GCC_PREFIX_HEADER = "ESConveyorBeltSample/ESConveyorBeltSample-Prefix.pch"; 396 | INFOPLIST_FILE = "ESConveyorBeltSample/ESConveyorBeltSample-Info.plist"; 397 | PRODUCT_NAME = "$(TARGET_NAME)"; 398 | WRAPPER_EXTENSION = app; 399 | }; 400 | name = Release; 401 | }; 402 | /* End XCBuildConfiguration section */ 403 | 404 | /* Begin XCConfigurationList section */ 405 | 5C50E8538C6442CA82FA7929 /* Build configuration list for PBXProject "ESConveyorBeltSample" */ = { 406 | isa = XCConfigurationList; 407 | buildConfigurations = ( 408 | 5C50E0702759D8B3022B033E /* Debug */, 409 | 5C50E010171715B8EEBBB5FB /* Release */, 410 | ); 411 | defaultConfigurationIsVisible = 0; 412 | defaultConfigurationName = Release; 413 | }; 414 | 5C50ECDA781FD695130D2F0C /* Build configuration list for PBXNativeTarget "ESConveyorBeltSample" */ = { 415 | isa = XCConfigurationList; 416 | buildConfigurations = ( 417 | 5C50E9CB902A2748FDA348B0 /* Debug */, 418 | 5C50EA5E981AA3483DB25AF2 /* Release */, 419 | ); 420 | defaultConfigurationIsVisible = 0; 421 | defaultConfigurationName = Release; 422 | }; 423 | /* End XCConfigurationList section */ 424 | }; 425 | rootObject = 5C50E605EDDEB34024C013C2 /* Project object */; 426 | } 427 | -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ESAppDelegate.h 3 | // ESConveyorSampleApp 4 | // 5 | // Created by Eduardo Scoz on 5/17/14. 6 | // Copyright (c) 2014 ESCOZ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ESAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ESAppDelegate.m 3 | // ESConveyorSampleApp 4 | // 5 | // Created by Eduardo Scoz on 5/17/14. 6 | // Copyright (c) 2014 ESCOZ. All rights reserved. 7 | // 8 | 9 | #import "ESAppDelegate.h" 10 | #import "ESConveyorSampleViewController.h" 11 | 12 | @implementation ESAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 17 | // Override point for customization after application launch. 18 | self.window.backgroundColor = [UIColor whiteColor]; 19 | self.window.rootViewController = [[ESConveyorSampleViewController alloc] init]; 20 | [self.window makeKeyAndVisible]; 21 | 22 | return YES; 23 | } 24 | 25 | - (void)applicationWillResignActive:(UIApplication *)application 26 | { 27 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 28 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 29 | 30 | } 31 | 32 | - (void)applicationDidEnterBackground:(UIApplication *)application 33 | { 34 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | 37 | } 38 | 39 | - (void)applicationWillEnterForeground:(UIApplication *)application 40 | { 41 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 42 | 43 | } 44 | 45 | - (void)applicationDidBecomeActive:(UIApplication *)application 46 | { 47 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 48 | 49 | } 50 | 51 | - (void)applicationWillTerminate:(UIApplication *)application 52 | { 53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 54 | 55 | } 56 | 57 | @end -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESConveyorBeltSample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CFBundleIdentifier 7 | com.escoz.${PRODUCT_NAME:rfc1034identifier} 8 | 9 | CFBundleDevelopmentRegion 10 | en 11 | CFBundleExecutable 12 | ${EXECUTABLE_NAME} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleSignature 20 | ???? 21 | 22 | CFBundleDisplayName 23 | ${PRODUCT_NAME} 24 | CFBundleVersion 25 | 1.0 26 | CFBundleShortVersionString 27 | 1.0 28 | LSRequiresIPhoneOS 29 | 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UISupportedInterfaceOrientations 35 | 36 | UIInterfaceOrientationPortrait 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | UISupportedInterfaceOrientations~ipad 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationPortraitUpsideDown 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESConveyorBeltSample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | 16 | #import 17 | 18 | #endif -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESConveyorSample1Builder.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 5/17/14. 3 | // Copyright (c) 2014 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface ESConveyorSample1Builder : NSObject 10 | 11 | + (NSArray *)buildTutorialWithTarget:(id)delegate; 12 | @end -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESConveyorSample1Builder.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 5/17/14. 3 | // Copyright (c) 2014 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorSample1Builder.h" 7 | #import "ESConveyorBelt.h" 8 | #import "ESConveyorSampleViewController.h" 9 | 10 | @interface ESTitleLabel : UILabel 11 | @end 12 | @implementation ESTitleLabel 13 | - (id)init 14 | { 15 | self = [super init]; 16 | if (self) { 17 | self.font = [UIFont fontWithName:@"Noteworthy-Bold" size:40]; 18 | self.textAlignment = NSTextAlignmentCenter; 19 | self.layer.shadowColor = [UIColor colorWithRed:0.6291 green:0.6290 blue:0.6291 alpha:1.0000].CGColor; 20 | self.layer.shadowOffset = CGSizeMake(2, 2); 21 | self.layer.shadowRadius = 1.0f; 22 | self.layer.shadowOpacity = 1.0f; 23 | } 24 | return self; 25 | } 26 | @end 27 | 28 | @interface ESCloseButton : UIButton 29 | @end 30 | @implementation ESCloseButton 31 | - (id)init 32 | { 33 | self = [super init]; 34 | if (self) { 35 | self.titleLabel.font = [UIFont fontWithName:@"Noteworthy-Bold" size:40]; 36 | self.layer.shadowColor = [UIColor colorWithRed:0.6291 green:0.6290 blue:0.6291 alpha:1.0000].CGColor; 37 | self.layer.shadowOffset = CGSizeMake(2, 2); 38 | self.layer.shadowRadius = 1.0f; 39 | self.layer.shadowOpacity = 1.0f; 40 | } 41 | return self; 42 | } 43 | 44 | @end 45 | 46 | @implementation ESConveyorSample1Builder 47 | 48 | 49 | + (NSArray *)buildTutorialWithTarget:(id)target 50 | { 51 | [[UIButton appearance] setTitleColor:[UIColor colorWithRed:0.4237 green:0.2847 blue:0.1927 alpha:1.0000] forState:UIControlStateNormal]; 52 | 53 | [UIPageControl appearance].pageIndicatorTintColor = [UIColor colorWithRed:0.4237 green:0.2847 blue:0.1927 alpha:1.0000]; 54 | [UIPageControl appearance].currentPageIndicatorTintColor = [UIColor colorWithRed:0.1328 green:0.6916 blue:0.8866 alpha:1.0000]; 55 | 56 | 57 | ESConveyorElement *title1 = [ESConveyorElement elementForLabelOfClass:[ESTitleLabel class] text:@"It's beach time!" center:CGPointMake(270, 60) size:CGSizeMake(440, 60)]; 58 | [title1 setInEffects:@[@(ESConveyorEffectEdgeTop)] outEffects: @[@(ESConveyorEffectFade)]]; 59 | title1.page = 0; 60 | ((UILabel *)title1.view).textColor = [UIColor colorWithRed:0.4237 green:0.2847 blue:0.1927 alpha:1.0000]; 61 | 62 | ESConveyorElement *title2 = [ESConveyorElement elementForLabelOfClass:[ESTitleLabel class] text:@"How about a Drink?" center:CGPointMake(270, 60) size:CGSizeMake(440, 60)]; 63 | [title2 setInEffects:@[@(ESConveyorEffectFade)] outEffects:@[@(ESConveyorEffectEdgeTop)]]; 64 | title2.page = 1; 65 | ((UILabel *)title2.view).textColor = [UIColor colorWithRed:0.4237 green:0.2847 blue:0.1927 alpha:1.0000]; 66 | 67 | ESConveyorElement *title3 = [ESConveyorElement elementForLabelOfClass:[ESTitleLabel class] text:@"Take your shoes off!" center:CGPointMake(270, 520) size:CGSizeMake(440, 60)]; 68 | [title3 setInEffects:@[@(ESConveyorEffectEdgeBottom), @(ESConveyorEffectFade)] outEffects:@[@(ESConveyorEffectEdgeLeft)]]; 69 | title3.page = 2; 70 | ((UILabel *)title3.view).textColor = [UIColor colorWithRed:0.1328 green:0.6916 blue:0.8866 alpha:1.0000]; 71 | 72 | ESConveyorElement *title4 = [ESConveyorElement elementForLabelOfClass:[ESTitleLabel class] text:@"Lets ride the waves, man!" center:CGPointMake(270, 520) size:CGSizeMake(440, 60)]; 73 | [title4 setInEffects:@[@(ESConveyorEffectEdgeRight)] outEffects:@[@(ESConveyorEffectFade)]]; 74 | title4.page = 3; 75 | ((UILabel *)title4.view).textColor = [UIColor colorWithRed:0.1328 green:0.6916 blue:0.8866 alpha:1.0000]; 76 | 77 | ESConveyorElement *bg = [ESConveyorElement elementForImageNamed:@"beach_bg"]; 78 | bg.inEffects = @[@(ESConveyorEffectParallax10), @(ESConveyorEffectFade)]; 79 | bg.outEffects = @[@(ESConveyorEffectParallax10), @(ESConveyorEffectFade)]; 80 | bg.paginationEffects = @[@(ESConveyorEffectParallax10)]; 81 | bg.inPage = 0; 82 | bg.outPage = 4; 83 | 84 | ESConveyorElement *img1 = [ESConveyorElement elementForImageNamed:@"umbrella" center:CGPointMake(260, 200)]; 85 | img1.inEffects = @[@(ESConveyorEffectEdgeBottom), @(ESConveyorEffectFade)]; 86 | img1.outEffects = @[@(ESConveyorEffectFade)]; 87 | img1.page = 0; 88 | ESConveyorElement *img2 = [ESConveyorElement elementForImageNamed:@"cocktail" center:CGPointMake(150, 200)]; 89 | img2.inEffects = @[@(ESConveyorEffectEdgeTop), @(ESConveyorEffectFade)]; 90 | img2.outEffects = @[@(ESConveyorEffectFade)]; 91 | img2.page = 1; 92 | ESConveyorElement *img3 = [ESConveyorElement elementForImageNamed:@"flip_flops" center:CGPointMake(350, 400)]; 93 | img3.inEffects = @[@(ESConveyorEffectEdgeLeft), @(ESConveyorEffectFade)]; 94 | img3.outEffects = @[@(ESConveyorEffectFade)]; 95 | img3.page = 2; 96 | ESConveyorElement *img4 = [ESConveyorElement elementForImageNamed:@"surfboard" center:CGPointMake(300, 400)]; 97 | img4.inEffects = @[@(ESConveyorEffectEdgeRight), @(ESConveyorEffectFade)]; 98 | img4.outEffects = @[@(ESConveyorEffectFade)]; 99 | img4.page = 3; 100 | 101 | ESConveyorElement *btExit = [ESConveyorElement elementForButtonOfClass:[ESCloseButton class] title:@"Lets go!" target:target action:@selector(buttonAction:) center:CGPointMake(270, 240)]; 102 | [btExit setInEffects:@[@(ESConveyorEffectEdgeBottom)] outEffects:@[@(ESConveyorEffectEdgeBottom)]]; 103 | btExit.inPage = 4; 104 | btExit.outPage = 4; 105 | 106 | ESConveyorPageControlElement *pagination = [[ESConveyorPageControlElement alloc] initWithClass:[UIPageControl class] center:CGPointMake(270, 580)]; 107 | pagination.inPage = 0; 108 | pagination.outPage = 5; 109 | [pagination setInEffects:@[@(ESConveyorEffectFade)] outEffects:nil]; 110 | 111 | NSArray *elements = @[bg, title1, img1, title2, img2, title3, img3, title4, img4, pagination, btExit]; 112 | return elements; 113 | } 114 | 115 | @end -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESConveyorSample2Builder.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 5/17/14. 3 | // Copyright (c) 2014 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface ESConveyorSample2Builder : NSObject 10 | 11 | + (NSArray *)buildTutorialWithTarget:(id)delegate; 12 | @end -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESConveyorSample2Builder.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 5/17/14. 3 | // Copyright (c) 2014 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorBelt.h" 7 | #import "ESConveyorSample2Builder.h" 8 | #import "ESConveyorSampleViewController.h" 9 | 10 | @implementation ESConveyorSample2Builder 11 | 12 | 13 | + (NSArray *)buildTutorialWithTarget:(id)target 14 | { 15 | 16 | [UIPageControl appearance].pageIndicatorTintColor = [UIColor blueColor]; 17 | [UIPageControl appearance].currentPageIndicatorTintColor = [UIColor greenColor]; 18 | 19 | ESConveyorElement *bt1 = [ESConveyorElement elementForButtonOfClass:[UIButton class] title:@"Here's my button" target:target action:@selector(buttonAction:) center:CGPointMake(270, 540)]; 20 | bt1.inEffects = @[@(ESConveyorEffectEdgeBottom)]; 21 | bt1.outEffects = @[@(ESConveyorEffectEdgeBottom)]; 22 | bt1.inPage = 1; 23 | bt1.outPage = 2; 24 | 25 | ESConveyorElement *p1 = [ESConveyorElement elementForImageNamed:@"goldengate.jpg"]; 26 | p1.center = CGPointMake(p1.center.x - 80, p1.center.y); 27 | [p1 setInEffects:@[@(ESConveyorEffectFade), @(ESConveyorEffectParallax20)] outEffects:@[@(ESConveyorEffectParallax20), @(ESConveyorEffectFade)]]; 28 | p1.paginationEffects = @[@(ESConveyorEffectParallax20)]; 29 | p1.inPage = 0; 30 | p1.outPage = 2; 31 | 32 | ESConveyorElement *p2 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(400, 100)]; 33 | [p2 setEffects:@[@(ESConveyorEffectFade), @(ESConveyorEffectParallax20)]]; 34 | p2.paginationEffects = @[ @(ESConveyorEffectParallax20)]; 35 | p2.inPage = 0; 36 | p2.outPage = 3; 37 | 38 | ESConveyorElement *p3 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(400, 240)]; 39 | [p3 setEffects:@[@(ESConveyorEffectParallax33), @(ESConveyorEffectFade)]]; 40 | p3.paginationEffects = @[ @(ESConveyorEffectParallax33)]; 41 | p3.inPage = 0; 42 | p3.outPage = 2; 43 | 44 | ESConveyorElement *p4 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(400, 380)]; 45 | [p4 setEffects:@[@(ESConveyorEffectParallax40), @(ESConveyorEffectFade)]]; 46 | p4.paginationEffects = @[ @(ESConveyorEffectParallax40)]; 47 | p4.inPage = 0; 48 | p4.outPage = 1; 49 | 50 | ESConveyorElement *p5 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(400, 520)]; 51 | [p5 setEffects:@[@(ESConveyorEffectParallax50), @(ESConveyorEffectFade)]]; 52 | p5.paginationEffects = @[ @(ESConveyorEffectParallax50)]; 53 | p5.inPage = 0; 54 | p5.outPage = 0; 55 | 56 | ESConveyorElement *p6 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(150, 400)]; 57 | [p6 setEffects:@[@(ESConveyorEffectParallax200), @(ESConveyorEffectFade)]]; 58 | p6.paginationEffects = @[@(ESConveyorEffectParallax200)]; 59 | p6.page = 0; 60 | p6.outPage = 2; 61 | 62 | ESConveyorElement *p7 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(150, 520)]; 63 | [p7 setEffects:@[@(ESConveyorEffectParallax150), @(ESConveyorEffectFade)]]; 64 | p7.paginationEffects = @[ @(ESConveyorEffectParallax150)]; 65 | p7.page = 0; 66 | p7.outPage = 2; 67 | 68 | ESConveyorElement *bacon1 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(150, 400)]; 69 | bacon1.inEffects = @[@(ESConveyorEffectEdgeBottom), @(ESConveyorEffectFade)]; 70 | bacon1.outEffects = @[@(ESConveyorEffectFade)]; 71 | bacon1.page = 4; 72 | ESConveyorElement *bacon2 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(150, 200)]; 73 | bacon2.inEffects = @[@(ESConveyorEffectEdgeTop), @(ESConveyorEffectFade)]; 74 | bacon2.outEffects = @[@(ESConveyorEffectFade)]; 75 | bacon2.page = 4; 76 | ESConveyorElement *bacon3 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(350, 200)]; 77 | bacon3.inEffects = @[@(ESConveyorEffectEdgeLeft), @(ESConveyorEffectFade)]; 78 | bacon3.outEffects = @[@(ESConveyorEffectFade)]; 79 | bacon3.page = 4; 80 | ESConveyorElement *bacon4 = [ESConveyorElement elementForImageNamed:@"bacon" center:CGPointMake(350, 400)]; 81 | bacon4.inEffects = @[@(ESConveyorEffectEdgeRight), @(ESConveyorEffectFade)]; 82 | bacon4.outEffects = @[@(ESConveyorEffectFade)]; 83 | bacon4.page = 4; 84 | 85 | ESConveyorPageControlElement *pagination = [[ESConveyorPageControlElement alloc] initWithClass:[UIPageControl class] center:CGPointMake(270, 600)]; 86 | pagination.inPage = 0; 87 | pagination.outPage = 5; 88 | [pagination setInEffects:@[@(ESConveyorEffectFade)] outEffects:nil]; 89 | 90 | NSArray *elements = @[p1, p2, p3, p4, p5, p6, p7, bt1, bacon1, bacon2, bacon3, bacon4, pagination]; 91 | return elements; 92 | } 93 | 94 | @end -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESConveyorSampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 5/17/14. 3 | // Copyright (c) 2014 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface ESConveyorSampleViewController : UIViewController 10 | - (void)buttonAction:(id)buttonAction; 11 | @end -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/ESConveyorSampleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Eduardo Scoz on 5/17/14. 3 | // Copyright (c) 2014 ESCOZ. All rights reserved. 4 | // 5 | 6 | #import "ESConveyorSampleViewController.h" 7 | #import "ESConveyorBelt.h" 8 | #import "ESConveyorSample1Builder.h" 9 | #import "ESConveyorSample2Builder.h" 10 | 11 | @implementation ESConveyorSampleViewController 12 | { 13 | 14 | } 15 | 16 | #pragma mark - Sample Actions 17 | 18 | - (void)loadView 19 | { 20 | [super loadView]; 21 | UIButton *button1 = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 44)]; 22 | [button1 setTitle:@"Sample 1" forState:UIControlStateNormal]; 23 | [button1 addTarget:self action:@selector(handleSample1) forControlEvents:UIControlEventTouchUpInside]; 24 | [self.view addSubview:button1]; 25 | 26 | 27 | UIButton *button2 = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 100, 44)]; 28 | [button2 setTitle:@"Sample 2" forState:UIControlStateNormal]; 29 | [button2 addTarget:self action:@selector(handleSample2) forControlEvents:UIControlEventTouchUpInside]; 30 | [self.view addSubview:button2]; 31 | 32 | self.view.backgroundColor = [UIColor lightGrayColor]; 33 | self.view.tintColor = [UIColor blueColor]; 34 | } 35 | 36 | - (void)viewDidLoad 37 | { 38 | [super viewDidLoad]; 39 | [self performSelector:@selector(handleSample1) withObject:nil afterDelay:0.1]; 40 | } 41 | 42 | 43 | -(void)handleSample1 44 | { 45 | NSArray *elements = [ESConveyorSample1Builder buildTutorialWithTarget:self]; 46 | UIViewController *controller = [[ESConveyorController alloc] initWithPages:5 elements:elements]; 47 | controller.modalPresentationStyle = UIModalPresentationFormSheet; 48 | [self presentViewController:controller animated:YES completion:nil]; 49 | } 50 | 51 | -(void)handleSample2 52 | { 53 | NSArray *elements = [ESConveyorSample2Builder buildTutorialWithTarget:self]; 54 | UIViewController *controller = [[ESConveyorController alloc] initWithPages:6 elements:elements]; 55 | controller.modalPresentationStyle = UIModalPresentationFormSheet; 56 | [self presentViewController:controller animated:YES completion:nil]; 57 | } 58 | 59 | 60 | - (void)buttonAction:(id)buttonAction 61 | { 62 | [self dismissViewControllerAnimated:YES completion:nil]; 63 | } 64 | 65 | 66 | @end -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/bacon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/bacon@2x.png -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/beach_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/beach_bg.png -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/beach_chair@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/beach_chair@2x.png -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/cocktail@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/cocktail@2x.png -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/flip_flops@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/flip_flops@2x.png -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/flippers@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/flippers@2x.png -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/goldengate@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/goldengate@2x.jpg -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/surfboard@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/surfboard@2x.png -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/Resources/umbrella@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/escoz/ESConveyorBelt/b517e1ba150992c81ffbfbd47708660a2c2f62ef/Example/ESConveyorBeltSample/Resources/umbrella@2x.png -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | -------------------------------------------------------------------------------- /Example/ESConveyorBeltSample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ESConveyorBeltSample 4 | // 5 | // Created by Eduardo Scoz on 5/17/14. 6 | // Copyright (c) 2014 ESCOZ inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ESAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([ESAppDelegate class])); 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Eduardo Scoz 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESConveyorBelt 2 | 3 | [![Version](http://cocoapod-badges.herokuapp.com/v/ESConveyorBelt/badge.png)](http://cocoadocs.org/docsets/ESConveyorBelt) 4 | [![Platform](http://cocoapod-badges.herokuapp.com/p/ESConveyorBelt/badge.png)](http://cocoadocs.org/docsets/ESConveyorBelt) 5 | 6 | ## Usage 7 | 8 | ESConveyorBelt allows you to easily create parallax-like effects for a tutorial screen for iOS. 9 | 10 | Included is a sample app with some of the effects possible: 11 | 12 | ![Sample](https://raw.githubusercontent.com/escoz/ESConveyorBelt/master/ESConveyorBelt.gif) 13 | 14 | To run the example project; clone the repo and open the project under the Example folder. 15 | 16 | ## Installation 17 | 18 | ESConveyorBelt is available through [CocoaPods](http://cocoapods.org), to install 19 | it simply add the following line to your Podfile: 20 | 21 | pod "ESConveyorBelt" 22 | 23 | ## Author 24 | 25 | Eduardo Scoz, eduardoscoz@gmail.com 26 | 27 | ## License 28 | 29 | ESConveyorBelt is available under the MIT license. See the LICENSE file for more info. 30 | 31 | Icons in the sample from [VisualPharm](http://www.visualpharm.com/vacation_icon_set/) -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | desc "Runs the specs [EMPTY]" 2 | task :spec do 3 | # Provide your own implementation 4 | end 5 | 6 | task :version do 7 | git_remotes = `git remote`.strip.split("\n") 8 | 9 | if git_remotes.count > 0 10 | puts "-- fetching version number from github" 11 | sh 'git fetch' 12 | 13 | remote_version = remote_spec_version 14 | end 15 | 16 | if remote_version.nil? 17 | puts "There is no current released version. You're about to release a new Pod." 18 | version = "0.0.1" 19 | else 20 | puts "The current released version of your pod is " + 21 | remote_spec_version.to_s() 22 | version = suggested_version_number 23 | end 24 | 25 | puts "Enter the version you want to release (" + version + ") " 26 | new_version_number = $stdin.gets.strip 27 | if new_version_number == "" 28 | new_version_number = version 29 | end 30 | 31 | replace_version_number(new_version_number) 32 | end 33 | 34 | desc "Release a new version of the Pod (append repo=name to push to a private spec repo)" 35 | task :release do 36 | # Allow override of spec repo name using `repo=private` after task name 37 | repo = ENV["repo"] || "master" 38 | 39 | puts "* Running version" 40 | sh "rake version" 41 | 42 | unless ENV['SKIP_CHECKS'] 43 | if `git symbolic-ref HEAD 2>/dev/null`.strip.split('/').last != 'master' 44 | $stderr.puts "[!] You need to be on the `master' branch in order to be able to do a release." 45 | exit 1 46 | end 47 | 48 | if `git tag`.strip.split("\n").include?(spec_version) 49 | $stderr.puts "[!] A tag for version `#{spec_version}' already exists. Change the version in the podspec" 50 | exit 1 51 | end 52 | 53 | puts "You are about to release `#{spec_version}`, is that correct? [y/n]" 54 | exit if $stdin.gets.strip.downcase != 'y' 55 | end 56 | 57 | puts "* Running specs" 58 | sh "rake spec" 59 | 60 | puts "* Linting the podspec" 61 | sh "pod lib lint" 62 | 63 | # Then release 64 | sh "git commit #{podspec_path} CHANGELOG.md -m 'Release #{spec_version}' --allow-empty" 65 | sh "git tag -a #{spec_version} -m 'Release #{spec_version}'" 66 | sh "git push origin master" 67 | sh "git push origin --tags" 68 | sh "pod push #{repo} #{podspec_path}" 69 | end 70 | 71 | # @return [Pod::Version] The version as reported by the Podspec. 72 | # 73 | def spec_version 74 | require 'cocoapods' 75 | spec = Pod::Specification.from_file(podspec_path) 76 | spec.version 77 | end 78 | 79 | # @return [Pod::Version] The version as reported by the Podspec from remote. 80 | # 81 | def remote_spec_version 82 | require 'cocoapods-core' 83 | 84 | if spec_file_exist_on_remote? 85 | remote_spec = eval(`git show origin/master:#{podspec_path}`) 86 | remote_spec.version 87 | else 88 | nil 89 | end 90 | end 91 | 92 | # @return [Bool] If the remote repository has a copy of the podpesc file or not. 93 | # 94 | def spec_file_exist_on_remote? 95 | test_condition = `if git rev-parse --verify --quiet origin/master:#{podspec_path} >/dev/null; 96 | then 97 | echo 'true' 98 | else 99 | echo 'false' 100 | fi` 101 | 102 | 'true' == test_condition.strip 103 | end 104 | 105 | # @return [String] The relative path of the Podspec. 106 | # 107 | def podspec_path 108 | podspecs = Dir.glob('*.podspec') 109 | if podspecs.count == 1 110 | podspecs.first 111 | else 112 | raise "Could not select a podspec" 113 | end 114 | end 115 | 116 | # @return [String] The suggested version number based on the local and remote 117 | # version numbers. 118 | # 119 | def suggested_version_number 120 | if spec_version != remote_spec_version 121 | spec_version.to_s() 122 | else 123 | next_version(spec_version).to_s() 124 | end 125 | end 126 | 127 | # @param [Pod::Version] version 128 | # the version for which you need the next version 129 | # 130 | # @note It is computed by bumping the last component of 131 | # the version string by 1. 132 | # 133 | # @return [Pod::Version] The version that comes next after 134 | # the version supplied. 135 | # 136 | def next_version(version) 137 | version_components = version.to_s().split("."); 138 | last = (version_components.last.to_i() + 1).to_s 139 | version_components[-1] = last 140 | Pod::Version.new(version_components.join(".")) 141 | end 142 | 143 | # @param [String] new_version_number 144 | # the new version number 145 | # 146 | # @note This methods replaces the version number in the podspec file 147 | # with a new version number. 148 | # 149 | # @return void 150 | # 151 | def replace_version_number(new_version_number) 152 | text = File.read(podspec_path) 153 | text.gsub!(/(s.version( )*= ")#{spec_version}(")/, 154 | "\\1#{new_version_number}\\3") 155 | File.open(podspec_path, "w") { |file| file.puts text } 156 | end 157 | --------------------------------------------------------------------------------