├── .gitignore ├── .travis.yml ├── LICENSE ├── MDCParallaxView.h ├── MDCParallaxView.m ├── MDCParallaxView.podspec ├── README.md ├── SampleApp.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── SampleApp.xcscheme └── SampleApp ├── AppDelegate.h ├── AppDelegate.m ├── Controllers ├── ImageViewController.h └── ImageViewController.m ├── Resources ├── Default-568h@2x.png └── background.png ├── SampleApp-Info.plist ├── SampleApp-Prefix.pch ├── en.lproj └── InfoPlist.strings └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | !default.xcworkspace 13 | xcuserdata 14 | *.xccheckout 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | script: xcodebuild -project SampleApp.xcodeproj -scheme SampleApp -sdk iphonesimulator clean build 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 modocache 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /MDCParallaxView.h: -------------------------------------------------------------------------------- 1 | // MDCParallaxView.h 2 | // 3 | // Copyright (c) 2012, 2014 to present, Brian Gesiak @modocache 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | 25 | 26 | #import 27 | 28 | 29 | @interface MDCParallaxView : UIView 30 | 31 | /// The scrollView used to display the parallax effect. 32 | @property (nonatomic, readonly) UIScrollView *scrollView; 33 | /// The delegate of scrollView. You must use this property when setting the scrollView delegate--attempting to set the scrollView delegate directly using `scrollView.delegate` will cause the parallax effect to stop updating. 34 | @property (nonatomic, weak) id scrollViewDelegate; 35 | /// The height of the background view when at rest. 36 | @property (nonatomic, assign) CGFloat backgroundHeight; 37 | /// YES if the backgroundView should handle touch input. 38 | @property (nonatomic, getter = isBackgroundInteractionEnabled) BOOL backgroundInteractionEnabled; 39 | 40 | /// *Designated initializer.* Creates a MDCParallaxView with the given views. 41 | /// @param backgroundView The view to be displayed in the background. This view scrolls slower than the foreground, creating the illusion that it is "further away". 42 | /// @param foregroundView The view to be displayed in the foreground. This view scrolls normally, and should be the one users primarily interact with. 43 | /// @return An initialized view object or nil if the object couldn't be created. 44 | - (id)initWithBackgroundView:(UIView *)backgroundView 45 | foregroundView:(UIView *)foregroundView; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /MDCParallaxView.m: -------------------------------------------------------------------------------- 1 | // MDCParallaxView.m 2 | // 3 | // Copyright (c) 2012, 2014 to present, Brian Gesiak @modocache 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | 25 | 26 | #import "MDCParallaxView.h" 27 | 28 | 29 | static void * kMDCForegroundViewObservationContext = &kMDCForegroundViewObservationContext; 30 | static void * kMDCBackgroundViewObservationContext = &kMDCBackgroundViewObservationContext; 31 | static CGFloat const kMDCParallaxViewDefaultHeight = 150.0f; 32 | 33 | @interface MDCParallaxView () 34 | @property (nonatomic, strong) UIView *backgroundView; 35 | @property (nonatomic, strong) UIView *foregroundView; 36 | @property (nonatomic, strong) UIScrollView *backgroundScrollView; 37 | @property (nonatomic, strong) UIScrollView *foregroundScrollView; 38 | @end 39 | 40 | 41 | @implementation MDCParallaxView 42 | 43 | 44 | #pragma mark - Object Lifecycle 45 | 46 | - (id)initWithBackgroundView:(UIView *)backgroundView foregroundView:(UIView *)foregroundView { 47 | self = [super init]; 48 | if (self) { 49 | _backgroundHeight = kMDCParallaxViewDefaultHeight; 50 | _backgroundView = backgroundView; 51 | _foregroundView = foregroundView; 52 | 53 | _backgroundScrollView = [UIScrollView new]; 54 | _backgroundScrollView.backgroundColor = [UIColor clearColor]; 55 | _backgroundScrollView.showsHorizontalScrollIndicator = NO; 56 | _backgroundScrollView.showsVerticalScrollIndicator = NO; 57 | _backgroundScrollView.scrollsToTop = NO; 58 | _backgroundScrollView.canCancelContentTouches = YES; 59 | [_backgroundScrollView addSubview:_backgroundView]; 60 | [self addSubview:_backgroundScrollView]; 61 | 62 | _foregroundScrollView = [UIScrollView new]; 63 | _foregroundScrollView.backgroundColor = [UIColor clearColor]; 64 | _foregroundScrollView.delegate = self; 65 | [_foregroundScrollView addSubview:_foregroundView]; 66 | [self addSubview:_foregroundScrollView]; 67 | 68 | [self addFrameObservers]; 69 | } 70 | return self; 71 | } 72 | 73 | - (void)dealloc { 74 | [self removeFrameObservers]; 75 | } 76 | 77 | 78 | #pragma mark - NSKeyValueObserving Protocol Methods 79 | 80 | - (void)observeValueForKeyPath:(NSString *)keyPath 81 | ofObject:(id)object 82 | change:(NSDictionary *)change 83 | context:(void *)context { 84 | if (context == kMDCForegroundViewObservationContext) { 85 | CGRect oldFrame = [self frameForObject:[change objectForKey:NSKeyValueChangeOldKey]]; 86 | [self updateForegroundFrameIfDifferent:oldFrame]; 87 | } else if (context == kMDCBackgroundViewObservationContext) { 88 | CGRect oldFrame = [self frameForObject:[change objectForKey:NSKeyValueChangeOldKey]]; 89 | [self updateBackgroundFrameIfDifferent:oldFrame]; 90 | } else { 91 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 92 | } 93 | } 94 | 95 | 96 | #pragma mark - NSObject Overrides 97 | 98 | - (void)forwardInvocation:(NSInvocation *)anInvocation { 99 | if ([self.scrollViewDelegate respondsToSelector:[anInvocation selector]]) { 100 | [anInvocation invokeWithTarget:self.scrollViewDelegate]; 101 | } else { 102 | [super forwardInvocation:anInvocation]; 103 | } 104 | } 105 | 106 | - (BOOL)respondsToSelector:(SEL)aSelector { 107 | return ([super respondsToSelector:aSelector] || 108 | [self.scrollViewDelegate respondsToSelector:aSelector]); 109 | } 110 | 111 | 112 | #pragma mark - UIView Overrides 113 | 114 | - (void)setFrame:(CGRect)frame { 115 | [super setFrame:frame]; 116 | [self updateBackgroundFrame]; 117 | [self updateForegroundFrame]; 118 | [self updateContentOffset]; 119 | } 120 | 121 | - (void)setAutoresizingMask:(UIViewAutoresizing)autoresizingMask { 122 | [super setAutoresizingMask:autoresizingMask]; 123 | self.backgroundView.autoresizingMask = autoresizingMask; 124 | self.backgroundScrollView.autoresizingMask = autoresizingMask; 125 | self.foregroundView.autoresizingMask = autoresizingMask; 126 | self.foregroundScrollView.autoresizingMask = autoresizingMask; 127 | } 128 | 129 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 130 | if ([self.backgroundView pointInside:point withEvent:event] && _backgroundInteractionEnabled) { 131 | CGFloat visibleBackgroundViewHeight = 132 | self.backgroundHeight - self.foregroundScrollView.contentOffset.y; 133 | if (point.y < visibleBackgroundViewHeight){ 134 | return [self.backgroundView hitTest:point withEvent:event]; 135 | } 136 | } 137 | 138 | return [super hitTest:point withEvent:event]; 139 | } 140 | 141 | 142 | #pragma mark - UIScrollViewDelegate Protocol Methods 143 | 144 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 145 | [self updateContentOffset]; 146 | if ([self.scrollViewDelegate respondsToSelector:_cmd]) { 147 | [self.scrollViewDelegate scrollViewDidScroll:scrollView]; 148 | } 149 | } 150 | 151 | #pragma mark - Public Interface 152 | 153 | - (UIScrollView *)scrollView { 154 | return self.foregroundScrollView; 155 | } 156 | 157 | - (void)setBackgroundHeight:(CGFloat)backgroundHeight { 158 | _backgroundHeight = backgroundHeight; 159 | [self updateBackgroundFrame]; 160 | [self updateForegroundFrame]; 161 | [self updateContentOffset]; 162 | } 163 | 164 | 165 | #pragma mark - Internal Methods 166 | 167 | #pragma mark Key-Value Observing 168 | 169 | - (void)addFrameObservers { 170 | [self addObserver:self forKeyPath:@"foregroundView.frame" 171 | options:NSKeyValueObservingOptionOld 172 | context:kMDCForegroundViewObservationContext]; 173 | [self addObserver:self forKeyPath:@"backgroundView.frame" 174 | options:NSKeyValueObservingOptionOld 175 | context:kMDCBackgroundViewObservationContext]; 176 | } 177 | 178 | - (void)removeFrameObservers { 179 | [self removeObserver:self forKeyPath:@"foregroundView.frame"]; 180 | [self removeObserver:self forKeyPath:@"backgroundView.frame"]; 181 | } 182 | 183 | - (void)updateForegroundFrameIfDifferent:(CGRect)oldFrame { 184 | if (!CGRectEqualToRect(self.foregroundView.frame, oldFrame)) { 185 | [self updateForegroundFrame]; 186 | } 187 | } 188 | 189 | - (void)updateBackgroundFrameIfDifferent:(CGRect)oldFrame { 190 | if (!CGRectEqualToRect(self.backgroundView.frame, oldFrame)) { 191 | [self updateBackgroundFrame]; 192 | } 193 | } 194 | 195 | - (CGRect)frameForObject:(id)frameObject { 196 | return frameObject == [NSNull null] ? CGRectNull : [frameObject CGRectValue]; 197 | } 198 | 199 | #pragma mark Parallax Effect 200 | 201 | - (void)updateBackgroundFrame { 202 | self.backgroundScrollView.frame = self.bounds; 203 | self.backgroundScrollView.contentSize = self.bounds.size; 204 | self.backgroundScrollView.contentOffset = CGPointZero; 205 | 206 | self.backgroundView.frame = 207 | CGRectMake(0.0f, 208 | floorf((self.backgroundHeight - CGRectGetHeight(self.backgroundView.frame))/2), 209 | CGRectGetWidth(self.frame), 210 | CGRectGetHeight(self.backgroundView.frame)); 211 | } 212 | 213 | - (void)updateForegroundFrame { 214 | self.foregroundView.frame = CGRectMake(0.0f, 215 | self.backgroundHeight, 216 | CGRectGetWidth(self.foregroundView.frame), 217 | CGRectGetHeight(self.foregroundView.frame)); 218 | 219 | self.foregroundScrollView.frame = self.bounds; 220 | self.foregroundScrollView.contentSize = 221 | CGSizeMake(CGRectGetWidth(self.foregroundView.frame), 222 | CGRectGetHeight(self.foregroundView.frame) + self.backgroundHeight); 223 | } 224 | 225 | - (void)updateContentOffset { 226 | CGFloat offsetY = self.foregroundScrollView.contentOffset.y; 227 | CGFloat threshold = CGRectGetHeight(self.backgroundView.frame) - self.backgroundHeight; 228 | 229 | if (offsetY > -threshold && offsetY < 0.0f) { 230 | self.backgroundScrollView.contentOffset = CGPointMake(0.0f, floorf(offsetY/2)); 231 | } else if (offsetY < 0.0f) { 232 | self.backgroundScrollView.contentOffset = CGPointMake(0.0f, offsetY + floorf(threshold/2)); 233 | } else { 234 | self.backgroundScrollView.contentOffset = CGPointMake(0.0f, offsetY); 235 | } 236 | } 237 | 238 | @end 239 | -------------------------------------------------------------------------------- /MDCParallaxView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'MDCParallaxView' 3 | s.version = '0.1.5' 4 | s.summary = 'Create a parallax effect using a custom container view, much like the top view of Path\'s timeline.' 5 | s.homepage = 'https://github.com/modocache/MDCParallaxView' 6 | s.license = 'MIT' 7 | s.author = { 'modocache' => 'modocache@gmail.com' } 8 | s.social_media_url = 'https://twitter.com/modocache' 9 | s.source = { :git => 'https://github.com/modocache/MDCParallaxView.git', :tag => "v#{s.version}" } 10 | s.source_files = '*.{h,m}' 11 | s.requires_arc = true 12 | s.platform = :ios, '5.0' 13 | s.framework = 'UIKit' 14 | end 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## MDCParallaxView 2 | 3 | [![Build Status](https://travis-ci.org/modocache/MDCParallaxView.svg?branch=master)](https://travis-ci.org/modocache/MDCParallaxView) 4 | 5 | Create a parallax effect using a custom container view, 6 | much like the top view of Path's timeline. 7 | 8 | ## Sample 9 | 10 | ![](http://i.imgflip.com/5z5b.gif) 11 | 12 | Sample usage is available in the [`SampleApp`](https://github.com/modocache/MDCParallaxView/blob/master/SampleApp/Controllers/ImageViewController.m#L43). 13 | Here's the gist: 14 | 15 | ```objc 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | 19 | // Create backgroud image view. 20 | UIImage *backgroundImage = [UIImage imageNamed:@"background.png"]; 21 | CGRect backgroundRect = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), backgroundImage.size.height); 22 | UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:backgroundRect]; 23 | backgroundImageView.image = backgroundImage; 24 | backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 25 | 26 | // Create foreground view. 27 | CGRect foregroundRect = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 400.0f); 28 | UIView *foregroundView = [[UIView alloc] initWithFrame:foregroundRect]; 29 | 30 | // Create parallax view with background and foreground views. 31 | // You can see additional configuration options in the SampleApp. 32 | MDCParallaxView *parallaxView = [[MDCParallaxView alloc] initWithBackgroundView:backgroundImageView 33 | foregroundView:foregroundView]; 34 | parallaxView.frame = self.view.bounds; 35 | parallaxView.backgroundHeight = 250.0f; 36 | parallaxView.scrollView.scrollsToTop = YES; 37 | [self.view addSubview:parallaxView]; 38 | } 39 | ``` 40 | 41 | ## Acknowledgements 42 | 43 | The content offset updates are based on those found in 44 | [PXParallaxViewController](https://github.com/tapi/PXParallaxViewController). 45 | While that project uses a custom `UIViewController`, this 46 | one uses a custom `UIView`, which I believe provides a better API. 47 | 48 | -------------------------------------------------------------------------------- /SampleApp.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DAA4C77318F8C72E00F6C4D6 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAA4C77218F8C72E00F6C4D6 /* Default-568h@2x.png */; }; 11 | DAB84CFB164755DE000AB1FE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAB84CFA164755DE000AB1FE /* UIKit.framework */; }; 12 | DAB84CFD164755DE000AB1FE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAB84CFC164755DE000AB1FE /* Foundation.framework */; }; 13 | DAB84CFF164755DE000AB1FE /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAB84CFE164755DE000AB1FE /* CoreGraphics.framework */; }; 14 | DAB84D05164755DE000AB1FE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DAB84D03164755DE000AB1FE /* InfoPlist.strings */; }; 15 | DAB84D07164755DE000AB1FE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB84D06164755DE000AB1FE /* main.m */; }; 16 | DAB84D0B164755DE000AB1FE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB84D0A164755DE000AB1FE /* AppDelegate.m */; }; 17 | DAB84D2116475797000AB1FE /* MDCParallaxView.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB84D2016475797000AB1FE /* MDCParallaxView.m */; }; 18 | DAB84D251647586C000AB1FE /* ImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB84D241647586C000AB1FE /* ImageViewController.m */; }; 19 | DAC3D8E516475B2A00320551 /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = DAC3D8E416475B2A00320551 /* background.png */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | DAA4C77218F8C72E00F6C4D6 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 24 | DAB84CF6164755DE000AB1FE /* SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | DAB84CFA164755DE000AB1FE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 26 | DAB84CFC164755DE000AB1FE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 27 | DAB84CFE164755DE000AB1FE /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 28 | DAB84D02164755DE000AB1FE /* SampleApp-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SampleApp-Info.plist"; sourceTree = ""; }; 29 | DAB84D04164755DE000AB1FE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 30 | DAB84D06164755DE000AB1FE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 31 | DAB84D08164755DE000AB1FE /* SampleApp-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SampleApp-Prefix.pch"; sourceTree = ""; }; 32 | DAB84D09164755DE000AB1FE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 33 | DAB84D0A164755DE000AB1FE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 34 | DAB84D1F16475797000AB1FE /* MDCParallaxView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MDCParallaxView.h; sourceTree = ""; }; 35 | DAB84D2016475797000AB1FE /* MDCParallaxView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MDCParallaxView.m; sourceTree = ""; }; 36 | DAB84D231647586C000AB1FE /* ImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageViewController.h; sourceTree = ""; }; 37 | DAB84D241647586C000AB1FE /* ImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageViewController.m; sourceTree = ""; }; 38 | DAC3D8E416475B2A00320551 /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background.png; sourceTree = ""; }; 39 | /* End PBXFileReference section */ 40 | 41 | /* Begin PBXFrameworksBuildPhase section */ 42 | DAB84CF3164755DE000AB1FE /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | DAB84CFB164755DE000AB1FE /* UIKit.framework in Frameworks */, 47 | DAB84CFD164755DE000AB1FE /* Foundation.framework in Frameworks */, 48 | DAB84CFF164755DE000AB1FE /* CoreGraphics.framework in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | DAB84CEB164755DE000AB1FE = { 56 | isa = PBXGroup; 57 | children = ( 58 | DAB84D1F16475797000AB1FE /* MDCParallaxView.h */, 59 | DAB84D2016475797000AB1FE /* MDCParallaxView.m */, 60 | DAB84D00164755DE000AB1FE /* SampleApp */, 61 | DAB84CF9164755DE000AB1FE /* Frameworks */, 62 | DAB84CF7164755DE000AB1FE /* Products */, 63 | ); 64 | sourceTree = ""; 65 | }; 66 | DAB84CF7164755DE000AB1FE /* Products */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | DAB84CF6164755DE000AB1FE /* SampleApp.app */, 70 | ); 71 | name = Products; 72 | sourceTree = ""; 73 | }; 74 | DAB84CF9164755DE000AB1FE /* Frameworks */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | DAB84CFA164755DE000AB1FE /* UIKit.framework */, 78 | DAB84CFC164755DE000AB1FE /* Foundation.framework */, 79 | DAB84CFE164755DE000AB1FE /* CoreGraphics.framework */, 80 | ); 81 | name = Frameworks; 82 | sourceTree = ""; 83 | }; 84 | DAB84D00164755DE000AB1FE /* SampleApp */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | DAB84D09164755DE000AB1FE /* AppDelegate.h */, 88 | DAB84D0A164755DE000AB1FE /* AppDelegate.m */, 89 | DAB84D221647584D000AB1FE /* Controllers */, 90 | DAC3D8E316475B2A00320551 /* Resources */, 91 | DAB84D01164755DE000AB1FE /* Supporting Files */, 92 | ); 93 | path = SampleApp; 94 | sourceTree = ""; 95 | }; 96 | DAB84D01164755DE000AB1FE /* Supporting Files */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | DAB84D02164755DE000AB1FE /* SampleApp-Info.plist */, 100 | DAB84D03164755DE000AB1FE /* InfoPlist.strings */, 101 | DAB84D06164755DE000AB1FE /* main.m */, 102 | DAB84D08164755DE000AB1FE /* SampleApp-Prefix.pch */, 103 | ); 104 | name = "Supporting Files"; 105 | sourceTree = ""; 106 | }; 107 | DAB84D221647584D000AB1FE /* Controllers */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | DAB84D231647586C000AB1FE /* ImageViewController.h */, 111 | DAB84D241647586C000AB1FE /* ImageViewController.m */, 112 | ); 113 | path = Controllers; 114 | sourceTree = ""; 115 | }; 116 | DAC3D8E316475B2A00320551 /* Resources */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | DAA4C77218F8C72E00F6C4D6 /* Default-568h@2x.png */, 120 | DAC3D8E416475B2A00320551 /* background.png */, 121 | ); 122 | path = Resources; 123 | sourceTree = ""; 124 | }; 125 | /* End PBXGroup section */ 126 | 127 | /* Begin PBXNativeTarget section */ 128 | DAB84CF5164755DE000AB1FE /* SampleApp */ = { 129 | isa = PBXNativeTarget; 130 | buildConfigurationList = DAB84D14164755DE000AB1FE /* Build configuration list for PBXNativeTarget "SampleApp" */; 131 | buildPhases = ( 132 | DAB84CF2164755DE000AB1FE /* Sources */, 133 | DAB84CF3164755DE000AB1FE /* Frameworks */, 134 | DAB84CF4164755DE000AB1FE /* Resources */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = SampleApp; 141 | productName = SampleApp; 142 | productReference = DAB84CF6164755DE000AB1FE /* SampleApp.app */; 143 | productType = "com.apple.product-type.application"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | DAB84CED164755DE000AB1FE /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastUpgradeCheck = 0510; 152 | ORGANIZATIONNAME = modocache; 153 | }; 154 | buildConfigurationList = DAB84CF0164755DE000AB1FE /* Build configuration list for PBXProject "SampleApp" */; 155 | compatibilityVersion = "Xcode 3.2"; 156 | developmentRegion = English; 157 | hasScannedForEncodings = 0; 158 | knownRegions = ( 159 | en, 160 | ); 161 | mainGroup = DAB84CEB164755DE000AB1FE; 162 | productRefGroup = DAB84CF7164755DE000AB1FE /* Products */; 163 | projectDirPath = ""; 164 | projectRoot = ""; 165 | targets = ( 166 | DAB84CF5164755DE000AB1FE /* SampleApp */, 167 | ); 168 | }; 169 | /* End PBXProject section */ 170 | 171 | /* Begin PBXResourcesBuildPhase section */ 172 | DAB84CF4164755DE000AB1FE /* Resources */ = { 173 | isa = PBXResourcesBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | DAB84D05164755DE000AB1FE /* InfoPlist.strings in Resources */, 177 | DAC3D8E516475B2A00320551 /* background.png in Resources */, 178 | DAA4C77318F8C72E00F6C4D6 /* Default-568h@2x.png in Resources */, 179 | ); 180 | runOnlyForDeploymentPostprocessing = 0; 181 | }; 182 | /* End PBXResourcesBuildPhase section */ 183 | 184 | /* Begin PBXSourcesBuildPhase section */ 185 | DAB84CF2164755DE000AB1FE /* Sources */ = { 186 | isa = PBXSourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | DAB84D07164755DE000AB1FE /* main.m in Sources */, 190 | DAB84D0B164755DE000AB1FE /* AppDelegate.m in Sources */, 191 | DAB84D2116475797000AB1FE /* MDCParallaxView.m in Sources */, 192 | DAB84D251647586C000AB1FE /* ImageViewController.m in Sources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXSourcesBuildPhase section */ 197 | 198 | /* Begin PBXVariantGroup section */ 199 | DAB84D03164755DE000AB1FE /* InfoPlist.strings */ = { 200 | isa = PBXVariantGroup; 201 | children = ( 202 | DAB84D04164755DE000AB1FE /* en */, 203 | ); 204 | name = InfoPlist.strings; 205 | sourceTree = ""; 206 | }; 207 | /* End PBXVariantGroup section */ 208 | 209 | /* Begin XCBuildConfiguration section */ 210 | DAB84D12164755DE000AB1FE /* Debug */ = { 211 | isa = XCBuildConfiguration; 212 | buildSettings = { 213 | ALWAYS_SEARCH_USER_PATHS = NO; 214 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 215 | CLANG_CXX_LIBRARY = "libc++"; 216 | CLANG_ENABLE_OBJC_ARC = YES; 217 | CLANG_WARN_EMPTY_BODY = YES; 218 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 219 | CODE_SIGN_IDENTITY = "iPhone Developer"; 220 | COPY_PHASE_STRIP = NO; 221 | GCC_C_LANGUAGE_STANDARD = gnu99; 222 | GCC_DYNAMIC_NO_PIC = NO; 223 | GCC_OPTIMIZATION_LEVEL = 0; 224 | GCC_PREPROCESSOR_DEFINITIONS = ( 225 | "DEBUG=1", 226 | "$(inherited)", 227 | ); 228 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 229 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 230 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 231 | GCC_WARN_UNUSED_VARIABLE = YES; 232 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 233 | ONLY_ACTIVE_ARCH = YES; 234 | SDKROOT = iphoneos; 235 | TARGETED_DEVICE_FAMILY = "1,2"; 236 | }; 237 | name = Debug; 238 | }; 239 | DAB84D13164755DE000AB1FE /* Release */ = { 240 | isa = XCBuildConfiguration; 241 | buildSettings = { 242 | ALWAYS_SEARCH_USER_PATHS = NO; 243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 244 | CLANG_CXX_LIBRARY = "libc++"; 245 | CLANG_ENABLE_OBJC_ARC = YES; 246 | CLANG_WARN_EMPTY_BODY = YES; 247 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 248 | CODE_SIGN_IDENTITY = "iPhone Distribution"; 249 | COPY_PHASE_STRIP = YES; 250 | GCC_C_LANGUAGE_STANDARD = gnu99; 251 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 252 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 253 | GCC_WARN_UNUSED_VARIABLE = YES; 254 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 255 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 256 | SDKROOT = iphoneos; 257 | TARGETED_DEVICE_FAMILY = "1,2"; 258 | VALIDATE_PRODUCT = YES; 259 | }; 260 | name = Release; 261 | }; 262 | DAB84D15164755DE000AB1FE /* Debug */ = { 263 | isa = XCBuildConfiguration; 264 | buildSettings = { 265 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 266 | GCC_PREFIX_HEADER = "SampleApp/SampleApp-Prefix.pch"; 267 | INFOPLIST_FILE = "SampleApp/SampleApp-Info.plist"; 268 | PRODUCT_NAME = "$(TARGET_NAME)"; 269 | WRAPPER_EXTENSION = app; 270 | }; 271 | name = Debug; 272 | }; 273 | DAB84D16164755DE000AB1FE /* Release */ = { 274 | isa = XCBuildConfiguration; 275 | buildSettings = { 276 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 277 | GCC_PREFIX_HEADER = "SampleApp/SampleApp-Prefix.pch"; 278 | INFOPLIST_FILE = "SampleApp/SampleApp-Info.plist"; 279 | PRODUCT_NAME = "$(TARGET_NAME)"; 280 | WRAPPER_EXTENSION = app; 281 | }; 282 | name = Release; 283 | }; 284 | /* End XCBuildConfiguration section */ 285 | 286 | /* Begin XCConfigurationList section */ 287 | DAB84CF0164755DE000AB1FE /* Build configuration list for PBXProject "SampleApp" */ = { 288 | isa = XCConfigurationList; 289 | buildConfigurations = ( 290 | DAB84D12164755DE000AB1FE /* Debug */, 291 | DAB84D13164755DE000AB1FE /* Release */, 292 | ); 293 | defaultConfigurationIsVisible = 0; 294 | defaultConfigurationName = Release; 295 | }; 296 | DAB84D14164755DE000AB1FE /* Build configuration list for PBXNativeTarget "SampleApp" */ = { 297 | isa = XCConfigurationList; 298 | buildConfigurations = ( 299 | DAB84D15164755DE000AB1FE /* Debug */, 300 | DAB84D16164755DE000AB1FE /* Release */, 301 | ); 302 | defaultConfigurationIsVisible = 0; 303 | defaultConfigurationName = Release; 304 | }; 305 | /* End XCConfigurationList section */ 306 | }; 307 | rootObject = DAB84CED164755DE000AB1FE /* Project object */; 308 | } 309 | -------------------------------------------------------------------------------- /SampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /SampleApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // AppDelegate.h 2 | // 3 | // Copyright (c) 2012, 2014 to present, Brian Gesiak @modocache 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | 25 | 26 | #import 27 | 28 | 29 | @interface AppDelegate : UIResponder 30 | 31 | @property (strong, nonatomic) UIWindow *window; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /SampleApp/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // AppDelegate.m 2 | // 3 | // Copyright (c) 2012, 2014 to present, Brian Gesiak @modocache 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | 25 | 26 | #import "AppDelegate.h" 27 | #import "ImageViewController.h" 28 | 29 | 30 | @implementation AppDelegate 31 | 32 | 33 | #pragma mark - UIApplicationDelegate Protocol Methods 34 | 35 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 36 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 37 | self.window.backgroundColor = [UIColor whiteColor]; 38 | [self.window makeKeyAndVisible]; 39 | self.window.rootViewController = [ImageViewController new]; 40 | return YES; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /SampleApp/Controllers/ImageViewController.h: -------------------------------------------------------------------------------- 1 | // ImageViewController.h 2 | // 3 | // Copyright (c) 2012, 2014 to present, Brian Gesiak @modocache 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | 25 | 26 | #import 27 | 28 | 29 | @interface ImageViewController : UIViewController 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /SampleApp/Controllers/ImageViewController.m: -------------------------------------------------------------------------------- 1 | // ImageViewController.m 2 | // 3 | // Copyright (c) 2012, 2014 to present, Brian Gesiak @modocache 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | 25 | 26 | #import "ImageViewController.h" 27 | #import "MDCParallaxView.h" 28 | 29 | 30 | @interface ImageViewController () 31 | 32 | @end 33 | 34 | 35 | @implementation ImageViewController 36 | 37 | 38 | #pragma mark - UIViewController Overrides 39 | 40 | - (void)viewDidLoad { 41 | [super viewDidLoad]; 42 | 43 | UIImage *backgroundImage = [UIImage imageNamed:@"background.png"]; 44 | CGRect backgroundRect = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), backgroundImage.size.height); 45 | UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:backgroundRect]; 46 | backgroundImageView.image = backgroundImage; 47 | backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 48 | 49 | UITapGestureRecognizer *tapGesture = 50 | [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; 51 | [backgroundImageView addGestureRecognizer:tapGesture]; 52 | 53 | CGRect textRect = CGRectMake(0, 0, CGRectGetWidth(self.view.frame), 400.0f); 54 | UITextView *textView = [[UITextView alloc] initWithFrame:textRect]; 55 | textView.text = NSLocalizedString(@"Permission is hereby granted, free of charge, to any " 56 | @"person obtaining a copy of this software and associated " 57 | @"documentation files (the \"Software\"), to deal in the " 58 | @"Software without restriction, including without limitation " 59 | @"the rights to use, copy, modify, merge, publish, " 60 | @"distribute, sublicense, and/or sell copies of the " 61 | @"Software, and to permit persons to whom the Software is " 62 | @"furnished to do so, subject to the following " 63 | @"conditions...\"", nil); 64 | textView.textAlignment = NSTextAlignmentCenter; 65 | textView.font = [UIFont systemFontOfSize:14.0f]; 66 | textView.textColor = [UIColor darkTextColor]; 67 | textView.scrollsToTop = NO; 68 | textView.editable = NO; 69 | 70 | MDCParallaxView *parallaxView = [[MDCParallaxView alloc] initWithBackgroundView:backgroundImageView 71 | foregroundView:textView]; 72 | parallaxView.frame = self.view.bounds; 73 | parallaxView.autoresizingMask = UIViewAutoresizingFlexibleWidth; 74 | parallaxView.backgroundHeight = 250.0f; 75 | parallaxView.scrollView.scrollsToTop = YES; 76 | parallaxView.backgroundInteractionEnabled = YES; 77 | parallaxView.scrollViewDelegate = self; 78 | [self.view addSubview:parallaxView]; 79 | } 80 | 81 | 82 | #pragma mark - UIScrollViewDelegate Protocol Methods 83 | 84 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 85 | NSLog(@"%@:%@", [self class], NSStringFromSelector(_cmd)); 86 | } 87 | 88 | 89 | #pragma mark - Internal Methods 90 | 91 | - (void)handleTap:(UIGestureRecognizer *)gesture { 92 | NSLog(@"%@:%@", [self class], NSStringFromSelector(_cmd)); 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /SampleApp/Resources/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/modocache/MDCParallaxView/da0ffdfabf710b75f806c3cb0d19ac35054adace/SampleApp/Resources/Default-568h@2x.png -------------------------------------------------------------------------------- /SampleApp/Resources/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/modocache/MDCParallaxView/da0ffdfabf710b75f806c3cb0d19ac35054adace/SampleApp/Resources/background.png -------------------------------------------------------------------------------- /SampleApp/SampleApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.modocache.ios.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SampleApp/SampleApp-Prefix.pch: -------------------------------------------------------------------------------- 1 | // SampleApp-Prefix.pch 2 | // 3 | // Copyright (c) 2012, 2014 to present, Brian Gesiak @modocache 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | 25 | 26 | #import 27 | 28 | 29 | #ifndef __IPHONE_3_0 30 | #warning "This project uses features only available in iOS SDK 3.0 and later." 31 | #endif 32 | 33 | 34 | #ifdef __OBJC__ 35 | #import 36 | #import 37 | #endif 38 | -------------------------------------------------------------------------------- /SampleApp/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /SampleApp/main.m: -------------------------------------------------------------------------------- 1 | // main.m 2 | // 3 | // Copyright (c) 2012, 2014 to present, Brian Gesiak @modocache 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | 25 | 26 | #import 27 | #import "AppDelegate.h" 28 | 29 | 30 | int main(int argc, char *argv[]) { 31 | @autoreleasepool { 32 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 33 | } 34 | } 35 | --------------------------------------------------------------------------------