├── .gitignore ├── MKParallaxView.podspec.json ├── MKParallaxView ├── MKGyroManager.h ├── MKGyroManager.m ├── MKParallaxManager.h ├── MKParallaxManager.m ├── MKParallaxView.h └── MKParallaxView.m ├── MKParallaxViewDemo ├── MKParallaxViewDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── morgankennedy.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── morgankennedy.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints.xcbkptlist │ │ └── xcschemes │ │ ├── MKParallaxViewDemo.xcscheme │ │ └── xcschememanagement.plist └── MKParallaxViewDemo │ ├── Application Bootstrap │ ├── MKAppDelegate.h │ └── MKAppDelegate.m │ ├── Frameworks │ └── SQLayout │ │ ├── SQLayout.h │ │ └── SQLayout.m │ ├── Modules │ ├── Controllers │ │ ├── MKViewController.h │ │ └── MKViewController.m │ └── Views │ │ ├── MKView.h │ │ └── MKView.m │ ├── Resources │ └── Images │ │ ├── Default-568h@2x.png │ │ ├── Default.png │ │ ├── Default@2x.png │ │ ├── NSTexturedFullScreenBackgroundColor.png │ │ └── blue-dots.jpg │ └── Supporting Files │ ├── MKDynamicViewDemo-Info.plist │ ├── MKParallaxViewDemo-Prefix.pch │ ├── en.lproj │ └── InfoPlist.strings │ └── main.m └── README.md /.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 | # CocoaPods 23 | Pods 24 | -------------------------------------------------------------------------------- /MKParallaxView.podspec.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "MKParallaxView", 4 | "version": "1.1.0", 5 | "summary": "MKParallaxView is an easy to use framework used to create the IOS 7 Parallax Effect (Dynamic Background) on any of your apps!", 6 | "description": " \t\tMKParallaxView is an easy to use framework used to create the IOS 7 Parallax Effect (Dynamic Background) on any of your apps!\n\n\t\t\t\t\t\tTreat it just like a UIImageView and by simply assigning an image to it with 1 line you have the exact same effect for the background of your app.\n", 7 | "homepage": "https://github.com/Morgan-Kennedy/MKParallaxView", 8 | "license": { 9 | "type": "MIT", 10 | "text": " \t\t\t\t\t\tCreated by Morgan Kennedy on 19/07/13.\n\n \t\t\t\t\t\tThis code is distributed under the terms and conditions of the MIT license.\n\n \t\t\t\t\t\tCopyright (c) 2013 Morgan Kennedy\n\n \t\t\t\t\t\tPermission is hereby granted, free of charge, to any person obtaining a copy\n \t\t\t\t\t\tof this software and associated documentation files (the \"Software\"), to deal\n \t\t\t\t\t\tin the Software without restriction, including without limitation the rights\n \t\t\t\t\t\tto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n \t\t\t\t\t\tcopies of the Software, and to permit persons to whom the Software is\n \t\t\t\t\t\tfurnished to do so, subject to the following conditions:\n\n \t\t\t\t\t\tThe above copyright notice and this permission notice shall be included in\n \t\t\t\t\t\tall copies or substantial portions of the Software.\n\n \t\t\t\t\t\tTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n \t\t\t\t\t\tIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n \t\t\t\t\t\tFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n \t\t\t\t\t\tAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n \t\t\t\t\t\tLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n \t\t\t\t\t\tOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n \t\t\t\t\t\tTHE SOFTWARE.\n\n" 11 | }, 12 | "authors": { 13 | "Morgan Kennedy": "morgan.j.kennedy@gmail.com" 14 | }, 15 | "platforms": { 16 | "ios": "5.0" 17 | }, 18 | "source": { 19 | "git": "https://github.com/noelrocha/MKParallaxView.git" 20 | }, 21 | "source_files": "MKParallaxView/**/*.{h,m}", 22 | "frameworks": "CoreMotion", 23 | "requires_arc": true 24 | } -------------------------------------------------------------------------------- /MKParallaxView/MKGyroManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // MKGyroManager.h 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 20/07/13. 6 | // 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | // 9 | // Copyright (c) 2013 Morgan Kennedy 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import 30 | 31 | /** 32 | This is a singleton instance of the gyroscope manager who's 33 | main purpose is to consistantly notify the app of the 34 | x, y, z, roll, pitch, & yaw information 35 | */ 36 | @class MKGyroManager; 37 | 38 | @protocol MKGyroManagerDelegate 39 | 40 | @optional 41 | /** 42 | Triggers each time the angles are calculated 43 | @param roll value as a float 44 | @param pitch value as a float 45 | @param yaw value as a float 46 | */ 47 | - (void)MKGyroManagerUpdatedRoll:(CGFloat)roll Pitch:(CGFloat)pitch Yaw:(CGFloat)yaw; 48 | 49 | @end 50 | 51 | @interface MKGyroManager : NSObject 52 | /** 53 | The delegate to send the policy 54 | */ 55 | @property (nonatomic, weak) id delegate; 56 | 57 | /** 58 | The last recorded Roll Value 59 | */ 60 | @property (nonatomic, assign, readonly) CGFloat roll; 61 | 62 | /** 63 | The last recorded Pitch Value 64 | */ 65 | @property (nonatomic, assign, readonly) CGFloat pitch; 66 | 67 | /** 68 | The last recorded Yaw Value 69 | */ 70 | @property (nonatomic, assign, readonly) CGFloat yaw; 71 | 72 | /** 73 | Initialises the gyro manager as a singleton 74 | */ 75 | + (MKGyroManager *)sharedGyroManager; 76 | 77 | /** 78 | Stops the gyro manager from reading the gyro when you don't need it 79 | note: on first initialise the gyro is started 80 | */ 81 | - (void)stopGyro; 82 | 83 | /** 84 | Start the gyro up again 85 | */ 86 | - (void)startGyro; 87 | 88 | @end 89 | 90 | /** 91 | Gives the same info in userInfo as - (void)MKGyroManagerUpdatedRoll:(CGFloat)roll Pitch:(CGFloat)pitch Yaw:(CGFloat)yaw; 92 | */ 93 | extern NSString *const MKGyroManagerUpdateAnglesNotification; -------------------------------------------------------------------------------- /MKParallaxView/MKGyroManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKGyroManager.m 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 20/07/13. 6 | // 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | // 9 | // Copyright (c) 2013 Morgan Kennedy 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import "MKGyroManager.h" 30 | #import 31 | 32 | #define defaultHertz 1.0f/60.0f 33 | #define defaultGyroUpdateInterval 0.1f 34 | 35 | #define degrees(x) ((180 * x) / M_PI) 36 | 37 | @interface MKGyroManager() 38 | 39 | @property (nonatomic, strong) CMMotionManager *motionManager; 40 | @property (nonatomic, strong) NSOperationQueue *operationQueue; 41 | @property (nonatomic, strong) NSTimer *timer; 42 | 43 | /** 44 | Calculates the angles in degrees of the device and fires 45 | the delegate and a notification with the information 46 | */ 47 | - (void)retrieveAngles; 48 | 49 | @end 50 | 51 | @implementation MKGyroManager 52 | 53 | #pragma mark - 54 | #pragma mark - Lifecycle Methods 55 | + (MKGyroManager *)sharedGyroManager 56 | { 57 | static MKGyroManager *sharedGyroManager = nil; 58 | static dispatch_once_t onceToken; 59 | dispatch_once(&onceToken, ^{ 60 | sharedGyroManager = [[MKGyroManager alloc] init]; 61 | }); 62 | return sharedGyroManager; 63 | } 64 | 65 | - (id)init 66 | { 67 | self = [super init]; 68 | 69 | if (self) 70 | { 71 | _motionManager = [[CMMotionManager alloc] init]; 72 | _motionManager.deviceMotionUpdateInterval = defaultHertz; 73 | [_motionManager startDeviceMotionUpdates]; 74 | 75 | _timer = [NSTimer scheduledTimerWithTimeInterval:defaultHertz 76 | target:self 77 | selector:@selector(retrieveAngles) 78 | userInfo:nil 79 | repeats:YES]; 80 | } 81 | 82 | return self; 83 | } 84 | 85 | #pragma mark - 86 | #pragma mark - Public Methods 87 | - (void)stopGyro 88 | { 89 | [self.timer invalidate]; 90 | self.timer = nil; 91 | } 92 | 93 | - (void)startGyro 94 | { 95 | self.timer = [NSTimer scheduledTimerWithTimeInterval:defaultHertz 96 | target:self 97 | selector:@selector(retrieveAngles) 98 | userInfo:nil 99 | repeats:YES]; 100 | } 101 | 102 | #pragma mark - 103 | #pragma mark - Private Methods 104 | - (void)retrieveAngles 105 | { 106 | CMDeviceMotion *motion = self.motionManager.deviceMotion; 107 | CMAttitude *attitude = motion.attitude; 108 | 109 | _roll = degrees(attitude.roll); 110 | _pitch = degrees(attitude.pitch); 111 | _yaw = degrees(attitude.yaw); 112 | 113 | if (self.delegate && [self.delegate respondsToSelector:@selector(MKGyroManagerUpdatedRoll:Pitch:Yaw:)]) 114 | { 115 | [self.delegate MKGyroManagerUpdatedRoll:self.roll Pitch:self.pitch Yaw:self.yaw]; 116 | } 117 | 118 | NSDictionary *userInfo = @{@"roll":[NSNumber numberWithFloat:self.roll], 119 | @"pitch":[NSNumber numberWithFloat:self.pitch], 120 | @"yaw":[NSNumber numberWithFloat:self.yaw]}; 121 | [[NSNotificationCenter defaultCenter] postNotificationName:MKGyroManagerUpdateAnglesNotification object:self userInfo:userInfo]; 122 | } 123 | 124 | @end 125 | 126 | NSString *const MKGyroManagerUpdateAnglesNotification = @"MKGyroManagerUpdateAnglesNotification"; 127 | -------------------------------------------------------------------------------- /MKParallaxView/MKParallaxManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // MKParallaxManager.h 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 19/07/13. 6 | // 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | // 9 | // Copyright (c) 2013 Morgan Kennedy 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import 30 | 31 | /** 32 | MKParallaxManager is in charge of all calculations relating to the parallax effect 33 | */ 34 | @class MKParallaxManager; 35 | 36 | @interface MKParallaxManager : NSObject 37 | 38 | /** 39 | Returns an inited instace of the parallax manager to work with 40 | @return standardParallaxManager The standard parallax manager 41 | */ 42 | + (MKParallaxManager *)standardParallaxManager; 43 | 44 | /** 45 | Generates a parallex position (frame) from a view frame (that it sits in), 46 | and the current pitch and roll 47 | @param viewFrame is the Frame of the whole parallax view 48 | @return the frame that the image should be moving to 49 | */ 50 | - (CGRect)parallexFrameWithViewFrame:(CGRect)viewFrame; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /MKParallaxView/MKParallaxManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKParallaxManager.m 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 19/07/13. 6 | // 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | // 9 | // Copyright (c) 2013 Morgan Kennedy 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import "MKParallaxManager.h" 30 | #import "MKGyroManager.h" 31 | 32 | #define zeroPointV 30.0f 33 | #define maxV 60.0f 34 | #define minV 0.0f 35 | #define zeroPointH 0.0f 36 | #define maxH 30.0f 37 | #define minH -30.0f 38 | #define sizePercentPadding 0.0163f 39 | 40 | @interface MKParallaxManager() 41 | /** 42 | Generates the current Frame based on the front facing angle and sideways tilt 43 | as well as the frame size 44 | */ 45 | - (CGRect)generateCurrentFrameUsingFrontAngle:(CGFloat)frontAngle SideTile:(CGFloat)sideTilt ViewFrame:(CGRect)viewFrame; 46 | 47 | @end 48 | 49 | @implementation MKParallaxManager 50 | 51 | #pragma mark - 52 | #pragma mark - Lifecycle Methods 53 | + (MKParallaxManager *)standardParallaxManager 54 | { 55 | MKParallaxManager *standardParallaxManager = [[MKParallaxManager alloc] init]; 56 | return standardParallaxManager; 57 | } 58 | 59 | - (id)init 60 | { 61 | self = [super init]; 62 | 63 | if (self) 64 | { 65 | [MKGyroManager sharedGyroManager]; 66 | } 67 | 68 | return self; 69 | } 70 | 71 | #pragma mark - 72 | #pragma mark - Public Methods 73 | - (CGRect)parallexFrameWithViewFrame:(CGRect)viewFrame 74 | { 75 | CGFloat roll = [[MKGyroManager sharedGyroManager] roll]; 76 | CGFloat pitch = [[MKGyroManager sharedGyroManager] pitch]; 77 | 78 | CGFloat frontAngle = zeroPointV; 79 | CGFloat sideTilt = zeroPointH; 80 | 81 | UIViewController *orientationController = [[UIViewController alloc] init]; 82 | 83 | if (orientationController.interfaceOrientation == UIInterfaceOrientationLandscapeRight) 84 | { 85 | frontAngle = roll * -1; 86 | sideTilt = pitch; 87 | } 88 | else if (orientationController.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) 89 | { 90 | frontAngle = roll; 91 | sideTilt = pitch * -1; 92 | } 93 | else if (orientationController.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) 94 | { 95 | frontAngle = pitch * -1; 96 | sideTilt = roll * -1; 97 | } 98 | else // Portrait Assumption 99 | { 100 | frontAngle = pitch; 101 | sideTilt = roll; 102 | } 103 | 104 | if (frontAngle < 0) 105 | { 106 | frontAngle = frontAngle * -1; 107 | } 108 | 109 | if (frontAngle > maxV) 110 | { 111 | frontAngle = maxV; 112 | } 113 | else if (frontAngle < minV) 114 | { 115 | frontAngle = minV; 116 | } 117 | 118 | if (sideTilt > maxH) 119 | { 120 | sideTilt = maxH; 121 | } 122 | else if (sideTilt < minH) 123 | { 124 | sideTilt = minH; 125 | } 126 | 127 | return [self generateCurrentFrameUsingFrontAngle:frontAngle SideTile:sideTilt ViewFrame:viewFrame]; 128 | } 129 | 130 | #pragma mark - 131 | #pragma mark - Private Methods 132 | - (CGRect)generateCurrentFrameUsingFrontAngle:(CGFloat)frontAngle SideTile:(CGFloat)sideTilt ViewFrame:(CGRect)viewFrame 133 | { 134 | CGFloat widthSingleSidePadding = viewFrame.size.width * sizePercentPadding; 135 | CGFloat heightSingleSidePadding = viewFrame.size.height * sizePercentPadding; 136 | 137 | CGFloat newWidth = viewFrame.size.width + (widthSingleSidePadding * 2); 138 | CGFloat newHeight = viewFrame.size.height + (heightSingleSidePadding * 2); 139 | 140 | CGFloat newX = 0 - widthSingleSidePadding; 141 | CGFloat newY = 0; 142 | 143 | if (sideTilt > zeroPointH) 144 | { 145 | CGFloat rightTiltPercent = sideTilt / maxH; 146 | CGFloat shiftFromCenter = rightTiltPercent * widthSingleSidePadding; 147 | newX = newX - shiftFromCenter; 148 | } 149 | else if (sideTilt < zeroPointH) 150 | { 151 | CGFloat leftTiltPercent = sideTilt / minH; 152 | CGFloat shiftFromCenter = leftTiltPercent * widthSingleSidePadding; 153 | newX = newX + shiftFromCenter; 154 | } 155 | 156 | if (frontAngle > zeroPointV) 157 | { 158 | CGFloat topTiltPercent = frontAngle / maxH; 159 | CGFloat shiftFromCenter = topTiltPercent * heightSingleSidePadding; 160 | newY = newY - shiftFromCenter; 161 | } 162 | else if (frontAngle < zeroPointV) 163 | { 164 | CGFloat bottomTiltPercent = frontAngle / minH; 165 | CGFloat shiftFromCenter = bottomTiltPercent * heightSingleSidePadding; 166 | newY = newY + shiftFromCenter; 167 | } 168 | 169 | return CGRectMake(newX, newY, newWidth, newHeight); 170 | } 171 | 172 | @end 173 | -------------------------------------------------------------------------------- /MKParallaxView/MKParallaxView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MKParallaxView.h 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 19/07/13. 6 | // 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | // 9 | // Copyright (c) 2013 Morgan Kennedy 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import 30 | 31 | @interface MKParallaxView : UIView 32 | 33 | /** 34 | The image to be set as the background which will shift with the gyro 35 | */ 36 | @property (nonatomic, strong) UIImage *backgroundImage; 37 | 38 | /** 39 | By default it is set to NO (no repeat) 40 | If YES then the bacground image will automatically repeat (great for a pattern image) 41 | */ 42 | @property (nonatomic, assign) BOOL backgroundShouldRepeat; 43 | 44 | /** 45 | The image view that sits within the frame of the view and shifts with the Gyro 46 | */ 47 | @property (nonatomic, strong) UIImageView *parallaxImageView; 48 | 49 | /** 50 | The rate at which the parallax view updates itself 51 | (think of it like frames per second) 52 | Default is 60 53 | */ 54 | @property (nonatomic, assign) NSInteger updateRate; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /MKParallaxView/MKParallaxView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKParallaxView.m 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 19/07/13. 6 | // 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | // 9 | // Copyright (c) 2013 Morgan Kennedy 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import "MKParallaxView.h" 30 | #import "MKParallaxManager.h" 31 | 32 | #define defaultUpdateRate 60 33 | 34 | @interface MKParallaxView() 35 | 36 | /** 37 | The view that everything goes in 38 | */ 39 | @property (nonatomic, strong) UIScrollView *frameScrollView; 40 | 41 | /** 42 | External manager handeling the logic of the Parallax effect 43 | */ 44 | @property (nonatomic, strong) MKParallaxManager *parallaxManager; 45 | 46 | /** 47 | Timer to update the view 48 | */ 49 | @property (nonatomic, strong) NSTimer *updateTimer; 50 | 51 | /** 52 | Animate Change from current position to new position 53 | */ 54 | - (void)updateParallaxImage; 55 | 56 | @end 57 | 58 | @implementation MKParallaxView 59 | 60 | - (id)initWithFrame:(CGRect)frame 61 | { 62 | self = [super initWithFrame:frame]; 63 | 64 | if (self) 65 | { 66 | [self initCommon]; 67 | } 68 | 69 | return self; 70 | } 71 | 72 | - (void)awakeFromNib 73 | { 74 | [self initCommon]; 75 | } 76 | 77 | - (void)initCommon 78 | { 79 | _backgroundShouldRepeat = NO; 80 | 81 | self.backgroundColor = [UIColor clearColor]; 82 | 83 | _updateRate = defaultUpdateRate; 84 | 85 | _parallaxManager = [MKParallaxManager standardParallaxManager]; 86 | 87 | _frameScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.frame.size.width, self.frame.size.height)]; 88 | _frameScrollView.scrollEnabled = NO; 89 | 90 | _parallaxImageView = [[UIImageView alloc] initWithFrame:[_parallaxManager parallexFrameWithViewFrame:_frameScrollView.frame]]; 91 | _parallaxImageView.backgroundColor = [UIColor clearColor]; 92 | _parallaxImageView.contentMode = UIViewContentModeScaleAspectFill; 93 | _parallaxImageView.clipsToBounds = YES; 94 | 95 | _updateTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0f / self.updateRate) 96 | target:self 97 | selector:@selector(updateParallaxImage) 98 | userInfo:nil 99 | repeats:YES]; 100 | } 101 | 102 | - (void)layoutSubviews 103 | { 104 | [super layoutSubviews]; 105 | 106 | self.frameScrollView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 107 | [self insertSubview:self.frameScrollView belowSubview:[self.subviews objectAtIndex:0]] ; 108 | 109 | [self updateParallaxImage]; 110 | [self.frameScrollView addSubview:self.parallaxImageView]; 111 | } 112 | 113 | #pragma mark - 114 | #pragma mark - Overriding Methods 115 | - (UIColor *)backgroundColor 116 | { 117 | return self.parallaxImageView.backgroundColor; 118 | } 119 | 120 | - (UIImage *)backgroundImage 121 | { 122 | return self.parallaxImageView.image; 123 | } 124 | 125 | - (UIViewContentMode)contentMode 126 | { 127 | return self.parallaxImageView.contentMode; 128 | } 129 | 130 | - (void)setBackgroundColor:(UIColor *)backgroundColor 131 | { 132 | self.parallaxImageView.backgroundColor = backgroundColor; 133 | } 134 | 135 | - (void)setBackgroundImage:(UIImage *)backgroundImage 136 | { 137 | self.parallaxImageView.image = backgroundImage; 138 | } 139 | 140 | - (void)setUpdateRate:(NSInteger)updateRate 141 | { 142 | _updateRate = updateRate; 143 | 144 | [self.updateTimer invalidate]; 145 | self.updateTimer = nil; 146 | 147 | self.updateTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0f / self.updateRate) 148 | target:self 149 | selector:@selector(updateParallaxImage) 150 | userInfo:nil 151 | repeats:YES]; 152 | } 153 | 154 | - (void)setContentMode:(UIViewContentMode)contentMode 155 | { 156 | self.parallaxImageView.contentMode = contentMode; 157 | } 158 | 159 | #pragma mark - 160 | #pragma mark - Private Methods 161 | - (void)updateParallaxImage 162 | { 163 | CGRect toFrame = [self.parallaxManager parallexFrameWithViewFrame:self.frame]; 164 | 165 | [UIView animateWithDuration:(1.0f / self.updateRate) animations:^{ 166 | self.parallaxImageView.frame = toFrame; 167 | }]; 168 | } 169 | 170 | @end 171 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8E29BB45179B68C500990B1B /* SQLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E29BB2F179B68C500990B1B /* SQLayout.m */; }; 11 | 8E29BB46179B68C500990B1B /* blue-dots.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8E29BB35179B68C500990B1B /* blue-dots.jpg */; }; 12 | 8E29BB47179B68C500990B1B /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E29BB36179B68C500990B1B /* Default-568h@2x.png */; }; 13 | 8E29BB48179B68C500990B1B /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E29BB37179B68C500990B1B /* Default.png */; }; 14 | 8E29BB49179B68C500990B1B /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E29BB38179B68C500990B1B /* Default@2x.png */; }; 15 | 8E29BB4A179B68C500990B1B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8E29BB3A179B68C500990B1B /* InfoPlist.strings */; }; 16 | 8E29BB4B179B68C500990B1B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E29BB3C179B68C500990B1B /* main.m */; }; 17 | 8E29BB4C179B68C500990B1B /* MKDynamicViewDemo-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8E29BB3D179B68C500990B1B /* MKDynamicViewDemo-Info.plist */; }; 18 | 8E29BB4D179B68C500990B1B /* MKAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E29BB41179B68C500990B1B /* MKAppDelegate.m */; }; 19 | 8E29BB4F179B695800990B1B /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E29BB4E179B695800990B1B /* CoreMotion.framework */; }; 20 | 8E29BB52179B6ABD00990B1B /* MKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E29BB51179B6ABD00990B1B /* MKViewController.m */; }; 21 | 8E29BB55179B6AE400990B1B /* MKView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E29BB54179B6AE400990B1B /* MKView.m */; }; 22 | 8E4749BF179B650C00E1B4B1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E4749BE179B650C00E1B4B1 /* UIKit.framework */; }; 23 | 8E4749C1179B650C00E1B4B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E4749C0179B650C00E1B4B1 /* Foundation.framework */; }; 24 | 8E4749C3179B650C00E1B4B1 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E4749C2179B650C00E1B4B1 /* CoreGraphics.framework */; }; 25 | 8E50048E17B56B2500E7B352 /* NSTexturedFullScreenBackgroundColor.png in Resources */ = {isa = PBXBuildFile; fileRef = 8E50048D17B56B2500E7B352 /* NSTexturedFullScreenBackgroundColor.png */; }; 26 | 8E671EA917CC89AB00E728B3 /* MKGyroManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E671EA417CC89AB00E728B3 /* MKGyroManager.m */; }; 27 | 8E671EAA17CC89AB00E728B3 /* MKParallaxManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E671EA617CC89AB00E728B3 /* MKParallaxManager.m */; }; 28 | 8E671EAB17CC89AB00E728B3 /* MKParallaxView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E671EA817CC89AB00E728B3 /* MKParallaxView.m */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 8E29BB2E179B68C500990B1B /* SQLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLayout.h; sourceTree = ""; }; 33 | 8E29BB2F179B68C500990B1B /* SQLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQLayout.m; sourceTree = ""; }; 34 | 8E29BB35179B68C500990B1B /* blue-dots.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "blue-dots.jpg"; sourceTree = ""; }; 35 | 8E29BB36179B68C500990B1B /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 36 | 8E29BB37179B68C500990B1B /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 37 | 8E29BB38179B68C500990B1B /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 38 | 8E29BB3B179B68C500990B1B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 39 | 8E29BB3C179B68C500990B1B /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 40 | 8E29BB3D179B68C500990B1B /* MKDynamicViewDemo-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "MKDynamicViewDemo-Info.plist"; sourceTree = ""; }; 41 | 8E29BB3E179B68C500990B1B /* MKParallaxViewDemo-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MKParallaxViewDemo-Prefix.pch"; sourceTree = ""; }; 42 | 8E29BB40179B68C500990B1B /* MKAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKAppDelegate.h; sourceTree = ""; }; 43 | 8E29BB41179B68C500990B1B /* MKAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKAppDelegate.m; sourceTree = ""; }; 44 | 8E29BB4E179B695800990B1B /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; 45 | 8E29BB50179B6ABD00990B1B /* MKViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKViewController.h; sourceTree = ""; }; 46 | 8E29BB51179B6ABD00990B1B /* MKViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKViewController.m; sourceTree = ""; }; 47 | 8E29BB53179B6AE400990B1B /* MKView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKView.h; sourceTree = ""; }; 48 | 8E29BB54179B6AE400990B1B /* MKView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKView.m; sourceTree = ""; }; 49 | 8E4749BA179B650C00E1B4B1 /* MKDynamicViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MKDynamicViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 8E4749BE179B650C00E1B4B1 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 51 | 8E4749C0179B650C00E1B4B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 52 | 8E4749C2179B650C00E1B4B1 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 53 | 8E50048D17B56B2500E7B352 /* NSTexturedFullScreenBackgroundColor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = NSTexturedFullScreenBackgroundColor.png; sourceTree = ""; }; 54 | 8E671EA317CC89AB00E728B3 /* MKGyroManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKGyroManager.h; sourceTree = ""; }; 55 | 8E671EA417CC89AB00E728B3 /* MKGyroManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKGyroManager.m; sourceTree = ""; }; 56 | 8E671EA517CC89AB00E728B3 /* MKParallaxManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKParallaxManager.h; sourceTree = ""; }; 57 | 8E671EA617CC89AB00E728B3 /* MKParallaxManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKParallaxManager.m; sourceTree = ""; }; 58 | 8E671EA717CC89AB00E728B3 /* MKParallaxView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKParallaxView.h; sourceTree = ""; }; 59 | 8E671EA817CC89AB00E728B3 /* MKParallaxView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKParallaxView.m; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 8E4749B7179B650C00E1B4B1 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | 8E29BB4F179B695800990B1B /* CoreMotion.framework in Frameworks */, 68 | 8E4749BF179B650C00E1B4B1 /* UIKit.framework in Frameworks */, 69 | 8E4749C1179B650C00E1B4B1 /* Foundation.framework in Frameworks */, 70 | 8E4749C3179B650C00E1B4B1 /* CoreGraphics.framework in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | /* End PBXFrameworksBuildPhase section */ 75 | 76 | /* Begin PBXGroup section */ 77 | 8E29BB25179B68C500990B1B /* Frameworks */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 8E671EA217CC89AB00E728B3 /* MKParallaxView */, 81 | 8E29BB2D179B68C500990B1B /* SQLayout */, 82 | ); 83 | path = Frameworks; 84 | sourceTree = ""; 85 | }; 86 | 8E29BB2D179B68C500990B1B /* SQLayout */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 8E29BB2E179B68C500990B1B /* SQLayout.h */, 90 | 8E29BB2F179B68C500990B1B /* SQLayout.m */, 91 | ); 92 | path = SQLayout; 93 | sourceTree = ""; 94 | }; 95 | 8E29BB30179B68C500990B1B /* Modules */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 8E29BB31179B68C500990B1B /* Controllers */, 99 | 8E29BB32179B68C500990B1B /* Views */, 100 | ); 101 | path = Modules; 102 | sourceTree = ""; 103 | }; 104 | 8E29BB31179B68C500990B1B /* Controllers */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 8E29BB50179B6ABD00990B1B /* MKViewController.h */, 108 | 8E29BB51179B6ABD00990B1B /* MKViewController.m */, 109 | ); 110 | path = Controllers; 111 | sourceTree = ""; 112 | }; 113 | 8E29BB32179B68C500990B1B /* Views */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 8E29BB53179B6AE400990B1B /* MKView.h */, 117 | 8E29BB54179B6AE400990B1B /* MKView.m */, 118 | ); 119 | path = Views; 120 | sourceTree = ""; 121 | }; 122 | 8E29BB33179B68C500990B1B /* Resources */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 8E29BB34179B68C500990B1B /* Images */, 126 | ); 127 | path = Resources; 128 | sourceTree = ""; 129 | }; 130 | 8E29BB34179B68C500990B1B /* Images */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 8E50048D17B56B2500E7B352 /* NSTexturedFullScreenBackgroundColor.png */, 134 | 8E29BB35179B68C500990B1B /* blue-dots.jpg */, 135 | 8E29BB36179B68C500990B1B /* Default-568h@2x.png */, 136 | 8E29BB37179B68C500990B1B /* Default.png */, 137 | 8E29BB38179B68C500990B1B /* Default@2x.png */, 138 | ); 139 | path = Images; 140 | sourceTree = ""; 141 | }; 142 | 8E29BB39179B68C500990B1B /* Supporting Files */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 8E29BB3A179B68C500990B1B /* InfoPlist.strings */, 146 | 8E29BB3C179B68C500990B1B /* main.m */, 147 | 8E29BB3D179B68C500990B1B /* MKDynamicViewDemo-Info.plist */, 148 | 8E29BB3E179B68C500990B1B /* MKParallaxViewDemo-Prefix.pch */, 149 | ); 150 | path = "Supporting Files"; 151 | sourceTree = ""; 152 | }; 153 | 8E29BB3F179B68C500990B1B /* Application Bootstrap */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 8E29BB40179B68C500990B1B /* MKAppDelegate.h */, 157 | 8E29BB41179B68C500990B1B /* MKAppDelegate.m */, 158 | ); 159 | path = "Application Bootstrap"; 160 | sourceTree = ""; 161 | }; 162 | 8E4749AF179B650C00E1B4B1 = { 163 | isa = PBXGroup; 164 | children = ( 165 | 8E4749C4179B650C00E1B4B1 /* MKParallaxViewDemo */, 166 | 8E4749BD179B650C00E1B4B1 /* Frameworks */, 167 | 8E4749BB179B650C00E1B4B1 /* Products */, 168 | ); 169 | sourceTree = ""; 170 | }; 171 | 8E4749BB179B650C00E1B4B1 /* Products */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 8E4749BA179B650C00E1B4B1 /* MKDynamicViewDemo.app */, 175 | ); 176 | name = Products; 177 | sourceTree = ""; 178 | }; 179 | 8E4749BD179B650C00E1B4B1 /* Frameworks */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 8E29BB4E179B695800990B1B /* CoreMotion.framework */, 183 | 8E4749BE179B650C00E1B4B1 /* UIKit.framework */, 184 | 8E4749C0179B650C00E1B4B1 /* Foundation.framework */, 185 | 8E4749C2179B650C00E1B4B1 /* CoreGraphics.framework */, 186 | ); 187 | name = Frameworks; 188 | sourceTree = ""; 189 | }; 190 | 8E4749C4179B650C00E1B4B1 /* MKParallaxViewDemo */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 8E29BB25179B68C500990B1B /* Frameworks */, 194 | 8E29BB30179B68C500990B1B /* Modules */, 195 | 8E29BB33179B68C500990B1B /* Resources */, 196 | 8E29BB39179B68C500990B1B /* Supporting Files */, 197 | 8E29BB3F179B68C500990B1B /* Application Bootstrap */, 198 | ); 199 | path = MKParallaxViewDemo; 200 | sourceTree = ""; 201 | }; 202 | 8E671EA217CC89AB00E728B3 /* MKParallaxView */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | 8E671EA317CC89AB00E728B3 /* MKGyroManager.h */, 206 | 8E671EA417CC89AB00E728B3 /* MKGyroManager.m */, 207 | 8E671EA517CC89AB00E728B3 /* MKParallaxManager.h */, 208 | 8E671EA617CC89AB00E728B3 /* MKParallaxManager.m */, 209 | 8E671EA717CC89AB00E728B3 /* MKParallaxView.h */, 210 | 8E671EA817CC89AB00E728B3 /* MKParallaxView.m */, 211 | ); 212 | name = MKParallaxView; 213 | path = ../../../MKParallaxView; 214 | sourceTree = ""; 215 | }; 216 | /* End PBXGroup section */ 217 | 218 | /* Begin PBXNativeTarget section */ 219 | 8E4749B9179B650C00E1B4B1 /* MKParallaxViewDemo */ = { 220 | isa = PBXNativeTarget; 221 | buildConfigurationList = 8E4749D8179B650C00E1B4B1 /* Build configuration list for PBXNativeTarget "MKParallaxViewDemo" */; 222 | buildPhases = ( 223 | 8E4749B6179B650C00E1B4B1 /* Sources */, 224 | 8E4749B7179B650C00E1B4B1 /* Frameworks */, 225 | 8E4749B8179B650C00E1B4B1 /* Resources */, 226 | ); 227 | buildRules = ( 228 | ); 229 | dependencies = ( 230 | ); 231 | name = MKParallaxViewDemo; 232 | productName = MKParallaxViewDemo; 233 | productReference = 8E4749BA179B650C00E1B4B1 /* MKDynamicViewDemo.app */; 234 | productType = "com.apple.product-type.application"; 235 | }; 236 | /* End PBXNativeTarget section */ 237 | 238 | /* Begin PBXProject section */ 239 | 8E4749B1179B650C00E1B4B1 /* Project object */ = { 240 | isa = PBXProject; 241 | attributes = { 242 | CLASSPREFIX = MK; 243 | LastUpgradeCheck = 0450; 244 | ORGANIZATIONNAME = "Morgan Kennedy"; 245 | }; 246 | buildConfigurationList = 8E4749B4179B650C00E1B4B1 /* Build configuration list for PBXProject "MKParallaxViewDemo" */; 247 | compatibilityVersion = "Xcode 3.2"; 248 | developmentRegion = English; 249 | hasScannedForEncodings = 0; 250 | knownRegions = ( 251 | en, 252 | ); 253 | mainGroup = 8E4749AF179B650C00E1B4B1; 254 | productRefGroup = 8E4749BB179B650C00E1B4B1 /* Products */; 255 | projectDirPath = ""; 256 | projectRoot = ""; 257 | targets = ( 258 | 8E4749B9179B650C00E1B4B1 /* MKParallaxViewDemo */, 259 | ); 260 | }; 261 | /* End PBXProject section */ 262 | 263 | /* Begin PBXResourcesBuildPhase section */ 264 | 8E4749B8179B650C00E1B4B1 /* Resources */ = { 265 | isa = PBXResourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | 8E29BB46179B68C500990B1B /* blue-dots.jpg in Resources */, 269 | 8E29BB47179B68C500990B1B /* Default-568h@2x.png in Resources */, 270 | 8E29BB48179B68C500990B1B /* Default.png in Resources */, 271 | 8E29BB49179B68C500990B1B /* Default@2x.png in Resources */, 272 | 8E29BB4A179B68C500990B1B /* InfoPlist.strings in Resources */, 273 | 8E29BB4C179B68C500990B1B /* MKDynamicViewDemo-Info.plist in Resources */, 274 | 8E50048E17B56B2500E7B352 /* NSTexturedFullScreenBackgroundColor.png in Resources */, 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | /* End PBXResourcesBuildPhase section */ 279 | 280 | /* Begin PBXSourcesBuildPhase section */ 281 | 8E4749B6179B650C00E1B4B1 /* Sources */ = { 282 | isa = PBXSourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | 8E29BB45179B68C500990B1B /* SQLayout.m in Sources */, 286 | 8E29BB4B179B68C500990B1B /* main.m in Sources */, 287 | 8E29BB4D179B68C500990B1B /* MKAppDelegate.m in Sources */, 288 | 8E29BB52179B6ABD00990B1B /* MKViewController.m in Sources */, 289 | 8E29BB55179B6AE400990B1B /* MKView.m in Sources */, 290 | 8E671EA917CC89AB00E728B3 /* MKGyroManager.m in Sources */, 291 | 8E671EAA17CC89AB00E728B3 /* MKParallaxManager.m in Sources */, 292 | 8E671EAB17CC89AB00E728B3 /* MKParallaxView.m in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | /* End PBXSourcesBuildPhase section */ 297 | 298 | /* Begin PBXVariantGroup section */ 299 | 8E29BB3A179B68C500990B1B /* InfoPlist.strings */ = { 300 | isa = PBXVariantGroup; 301 | children = ( 302 | 8E29BB3B179B68C500990B1B /* en */, 303 | ); 304 | name = InfoPlist.strings; 305 | sourceTree = ""; 306 | }; 307 | /* End PBXVariantGroup section */ 308 | 309 | /* Begin XCBuildConfiguration section */ 310 | 8E4749D6179B650C00E1B4B1 /* Debug */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 315 | CLANG_CXX_LIBRARY = "libc++"; 316 | CLANG_ENABLE_OBJC_ARC = YES; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 319 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 320 | COPY_PHASE_STRIP = NO; 321 | GCC_C_LANGUAGE_STANDARD = gnu99; 322 | GCC_DYNAMIC_NO_PIC = NO; 323 | GCC_OPTIMIZATION_LEVEL = 0; 324 | GCC_PREPROCESSOR_DEFINITIONS = ( 325 | "DEBUG=1", 326 | "$(inherited)", 327 | ); 328 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 329 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 330 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 331 | GCC_WARN_UNUSED_VARIABLE = YES; 332 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 333 | SDKROOT = iphoneos; 334 | TARGETED_DEVICE_FAMILY = "1,2"; 335 | }; 336 | name = Debug; 337 | }; 338 | 8E4749D7179B650C00E1B4B1 /* Release */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ALWAYS_SEARCH_USER_PATHS = NO; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_OBJC_ARC = YES; 345 | CLANG_WARN_EMPTY_BODY = YES; 346 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 347 | CODE_SIGN_IDENTITY = "iPhone Distribution"; 348 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; 349 | COPY_PHASE_STRIP = YES; 350 | GCC_C_LANGUAGE_STANDARD = gnu99; 351 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 352 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 355 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 356 | PROVISIONING_PROFILE = ""; 357 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; 358 | SDKROOT = iphoneos; 359 | TARGETED_DEVICE_FAMILY = "1,2"; 360 | VALIDATE_PRODUCT = YES; 361 | }; 362 | name = Release; 363 | }; 364 | 8E4749D9179B650C00E1B4B1 /* Debug */ = { 365 | isa = XCBuildConfiguration; 366 | buildSettings = { 367 | CODE_SIGN_IDENTITY = "iPhone Developer"; 368 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 369 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 370 | GCC_PREFIX_HEADER = "$(SRCROOT)/MKParallaxViewDemo/Supporting Files/MKParallaxViewDemo-Prefix.pch"; 371 | INFOPLIST_FILE = "MKParallaxViewDemo/Supporting Files/MKDynamicViewDemo-Info.plist"; 372 | PRODUCT_NAME = MKDynamicViewDemo; 373 | PROVISIONING_PROFILE = ""; 374 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; 375 | WRAPPER_EXTENSION = app; 376 | }; 377 | name = Debug; 378 | }; 379 | 8E4749DA179B650C00E1B4B1 /* Release */ = { 380 | isa = XCBuildConfiguration; 381 | buildSettings = { 382 | CODE_SIGN_IDENTITY = "iPhone Distribution"; 383 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; 384 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 385 | GCC_PREFIX_HEADER = "$(SRCROOT)/MKParallaxViewDemo/Supporting Files/MKParallaxViewDemo-Prefix.pch"; 386 | INFOPLIST_FILE = "MKParallaxViewDemo/Supporting Files/MKDynamicViewDemo-Info.plist"; 387 | PRODUCT_NAME = MKDynamicViewDemo; 388 | PROVISIONING_PROFILE = ""; 389 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; 390 | WRAPPER_EXTENSION = app; 391 | }; 392 | name = Release; 393 | }; 394 | /* End XCBuildConfiguration section */ 395 | 396 | /* Begin XCConfigurationList section */ 397 | 8E4749B4179B650C00E1B4B1 /* Build configuration list for PBXProject "MKParallaxViewDemo" */ = { 398 | isa = XCConfigurationList; 399 | buildConfigurations = ( 400 | 8E4749D6179B650C00E1B4B1 /* Debug */, 401 | 8E4749D7179B650C00E1B4B1 /* Release */, 402 | ); 403 | defaultConfigurationIsVisible = 0; 404 | defaultConfigurationName = Release; 405 | }; 406 | 8E4749D8179B650C00E1B4B1 /* Build configuration list for PBXNativeTarget "MKParallaxViewDemo" */ = { 407 | isa = XCConfigurationList; 408 | buildConfigurations = ( 409 | 8E4749D9179B650C00E1B4B1 /* Debug */, 410 | 8E4749DA179B650C00E1B4B1 /* Release */, 411 | ); 412 | defaultConfigurationIsVisible = 0; 413 | defaultConfigurationName = Release; 414 | }; 415 | /* End XCConfigurationList section */ 416 | }; 417 | rootObject = 8E4749B1179B650C00E1B4B1 /* Project object */; 418 | } 419 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo.xcodeproj/project.xcworkspace/xcuserdata/morgankennedy.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgan-Kennedy/MKParallaxView/e8e52db3e67b30cdeb778bd9961a126030f5bc01/MKParallaxViewDemo/MKParallaxViewDemo.xcodeproj/project.xcworkspace/xcuserdata/morgankennedy.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo.xcodeproj/project.xcworkspace/xcuserdata/morgankennedy.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo.xcodeproj/xcuserdata/morgankennedy.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo.xcodeproj/xcuserdata/morgankennedy.xcuserdatad/xcschemes/MKParallaxViewDemo.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 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo.xcodeproj/xcuserdata/morgankennedy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MKParallaxViewDemo.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8E4749B9179B650C00E1B4B1 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Application Bootstrap/MKAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // MKAppDelegate.h 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 21/07/13. 6 | // Copyright (c) 2013 Morgan Kennedy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MKAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Application Bootstrap/MKAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKAppDelegate.m 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 21/07/13. 6 | // Copyright (c) 2013 Morgan Kennedy. All rights reserved. 7 | // 8 | 9 | #import "MKAppDelegate.h" 10 | #import "MKViewController.h" 11 | 12 | @implementation MKAppDelegate 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.rootViewController = [[MKViewController alloc] init]; 19 | self.window.backgroundColor = [UIColor darkGrayColor]; 20 | [self.window makeKeyAndVisible]; 21 | return YES; 22 | } 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application 25 | { 26 | // 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. 27 | // 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. 28 | } 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application 31 | { 32 | // 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. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application 42 | { 43 | // 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. 44 | } 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application 47 | { 48 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 49 | } 50 | 51 | - (NSUInteger)supportedInterfaceOrientations { 52 | return UIInterfaceOrientationMaskAll; 53 | } 54 | 55 | - (BOOL) shouldAutorotate { 56 | return YES; 57 | } 58 | 59 | - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { 60 | return UIInterfaceOrientationLandscapeLeft; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Frameworks/SQLayout/SQLayout.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009-2010 Bradley Clayton. All rights reserved. 3 | 4 | SQLayout can be downloaded from: 5 | https://bitbucket.org/dotb/sqlayout/ 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the author nor the names of its contributors may be used 18 | to endorse or promote products derived from this software without specific 19 | prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #import 34 | 35 | enum { 36 | SQAlignHCenter = 1, 37 | SQAlignLeft = 1 << 2, 38 | SQAlignRight = 1 << 3, 39 | SQAlignExactHCenter = 1 << 4, 40 | SQAlignExactLeft = 1 << 5, 41 | SQAlignExactRight = 1 << 6, 42 | 43 | SQAlignVCenter = 1 << 7, 44 | SQAlignTop = 1 << 8, 45 | SQAlignBottom = 1 << 9, 46 | SQAlignExactVCenter = 1 << 10, 47 | SQAlignExactTop = 1 << 11, 48 | SQAlignExactBottom = 1 << 12, 49 | SQAlignNone = 1 << 13, 50 | }; 51 | typedef uint SQAlign; 52 | 53 | enum { 54 | SQPlaceOnLeft = 1, 55 | SQPlaceOnRight = 1 << 1, 56 | SQPlaceAbove = 1 << 2, 57 | SQPlaceBelow = 1 << 3, 58 | SQPlaceNone = 1 << 4, 59 | SQPlaceWithin = 1 << 4, 60 | }; 61 | typedef uint SQPlace; 62 | 63 | enum { 64 | SQSizeUseAllWidth = 1, 65 | SQSizeUseAllHeight = 1 << 1, 66 | SQSizeUseAvailableWidth = 1 << 2, 67 | SQSizeUseAvailableHeight = 1 << 3, 68 | }; 69 | typedef uint SQSize; 70 | 71 | enum { 72 | SQLAYOUT_HORIZONTAL_LEFT_OF = 1, 73 | SQLAYOUT_HORIZONTAL_RIGHT_OF = 2, 74 | SQLAYOUT_HORIZONTAL_CENTER = 3, 75 | SQLAYOUT_VERTICAL_ABOVE = 4, 76 | SQLAYOUT_VERTICAL_BELOW = 5, 77 | SQLAYOUT_VERTICAL_CENTER = 6, 78 | 79 | SQLAYOUT_HORIZONTAL_LEFT_ALIGN = 7, 80 | SQLAYOUT_HORIZONTAL_RIGHT_ALIGN = 8, 81 | SQLAYOUT_VERTICAL_TOP_ALIGN = 9, 82 | SQLAYOUT_VERTICAL_BOTTOM_ALIGN = 10 83 | }; 84 | typedef uint SQLAYOUT; 85 | 86 | @interface SQLayout : NSObject 87 | 88 | typedef struct SQPadding SQPadding; 89 | struct SQPadding { 90 | CGFloat left; 91 | CGFloat right; 92 | CGFloat top; 93 | CGFloat bottom; 94 | }; 95 | 96 | CG_INLINE SQPadding 97 | SQPaddingMake(CGFloat top, CGFloat bottom, CGFloat left, CGFloat right) 98 | { 99 | SQPadding padding; 100 | padding.top = top; padding.bottom = bottom; 101 | padding.left = left; padding.right = right; 102 | return padding; 103 | } 104 | 105 | CG_EXTERN const SQPadding SQPaddingZero; 106 | 107 | /* 108 | * A dynamic method which works out a users intentions based on the 109 | * configuration and types of the given Views. This method allows 110 | * the size to be controlled by the user. 111 | */ 112 | + (UIView*) layoutView:(UIView *) view relativeToView:(UIView*) relativeView 113 | placement:(SQPlace) placement alignment:(SQAlign) alignment 114 | withSize:(CGSize) size 115 | withPadding:(SQPadding) padding; 116 | 117 | + (UIView*) layoutView:(UIView *) view relativeToView:(UIView*) relativeView 118 | placement:(SQPlace) placement alignment:(SQAlign) alignment 119 | withWidth:(CGFloat) width withHeight:(CGFloat) height 120 | withPadding:(SQPadding) padding; 121 | 122 | @end -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Frameworks/SQLayout/SQLayout.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009-2010 Bradley Clayton. All rights reserved. 3 | 4 | SQLayout can be downloaded from: 5 | https://bitbucket.org/dotb/sqlayout/ 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the author nor the names of its contributors may be used 18 | to endorse or promote products derived from this software without specific 19 | prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #include "SQLayout.h" 34 | 35 | @interface SQLayout () 36 | // Layout a child view within a parent 37 | + (UIView*) layoutView:(UIView *) view withinParentView:(UIView*) parentView 38 | alignment:(SQAlign) alignment 39 | withWidth:(CGFloat) width withHeight:(CGFloat) height 40 | withPadding:(SQPadding) padding; 41 | 42 | // Layout a view relative to a peer 43 | + (UIView*) layoutView:(UIView *) view relativeToPeerView:(UIView*) relativeView 44 | placement:(SQPlace) placement alignment:(SQAlign) alignment 45 | withWidth:(CGFloat) width withHeight:(CGFloat) height 46 | withPadding:(SQPadding) padding; 47 | 48 | 49 | + (void)resizeUILabel:(UILabel *) label constrainedToTotalSize:(CGSize) size; 50 | @end 51 | 52 | @implementation SQLayout 53 | 54 | const SQPadding SQPaddingZero = { 55 | .top = 0., 56 | .bottom = 0., 57 | .left = 0., 58 | .right = 0. 59 | }; 60 | 61 | + (UIView*) layoutView:(UIView *) view relativeToView:(UIView*) relativeView 62 | placement:(SQPlace) placement alignment:(SQAlign) alignment 63 | withSize:(CGSize) size 64 | withPadding:(SQPadding) padding 65 | { 66 | return [SQLayout layoutView:view relativeToView:relativeView 67 | placement:placement alignment:alignment 68 | withWidth:size.width withHeight:size.height 69 | withPadding:padding]; 70 | } 71 | 72 | + (UIView*) layoutView:(UIView *) view relativeToView:(UIView*) relativeView 73 | placement:(SQPlace) placement alignment:(SQAlign) alignment 74 | withWidth:(CGFloat) width withHeight:(CGFloat) height 75 | withPadding:(SQPadding) padding 76 | 77 | { 78 | CGRect viewFrame = [view frame]; 79 | 80 | /* If the view is not placed within a superview, attempt to add 81 | * it to a superview based on it's placement strategy. 82 | */ 83 | if (![view superview] && (placement & SQPlaceWithin)) 84 | { 85 | [relativeView addSubview:view]; 86 | } 87 | else if (![view superview] && [relativeView superview]) 88 | { 89 | [[relativeView superview] addSubview:view]; 90 | } 91 | 92 | viewFrame.size.width = width; 93 | viewFrame.size.height = height; 94 | 95 | // Update the view with the correct size 96 | [view setFrame:viewFrame]; 97 | 98 | // Is the view a child of the relative View ? 99 | if ([view superview] == relativeView) 100 | { 101 | [self layoutView:view withinParentView:relativeView alignment:alignment 102 | withWidth:viewFrame.size.width withHeight:viewFrame.size.height 103 | withPadding:padding]; 104 | } 105 | else 106 | { 107 | // Assume the view is a peer of the relative view 108 | [self layoutView:view relativeToPeerView:relativeView 109 | placement:placement alignment:alignment 110 | withWidth:viewFrame.size.width withHeight:viewFrame.size.height 111 | withPadding:padding]; 112 | } 113 | 114 | // Round off the coordinate and size to ensure pixel perfect rendering 115 | viewFrame = [view frame]; 116 | viewFrame.origin.x = (int) viewFrame.origin.x; 117 | viewFrame.origin.y = (int) viewFrame.origin.y; 118 | viewFrame.size.width = (int) viewFrame.size.width; 119 | viewFrame.size.height = (int) viewFrame.size.height; 120 | [view setFrame:viewFrame]; 121 | 122 | return view; 123 | } 124 | 125 | 126 | 127 | // Layout a child view within a parent 128 | + (UIView*) layoutView:(UIView*) view withinParentView:(UIView*) parentView 129 | alignment:(SQAlign) alignment 130 | withWidth:(CGFloat) width withHeight:(CGFloat) height 131 | withPadding:(SQPadding) padding 132 | { 133 | CGRect frame = [view frame]; 134 | 135 | // Alignment 136 | if (alignment & SQAlignLeft) 137 | frame.origin.x = padding.left; 138 | 139 | if (alignment & SQAlignRight) 140 | frame.origin.x = parentView.bounds.size.width - width - padding.right; 141 | 142 | if (alignment & SQAlignExactLeft) 143 | frame.origin.x = 0; 144 | 145 | if (alignment & SQAlignExactRight) 146 | frame.origin.x = parentView.bounds.size.width - width; 147 | 148 | if (alignment & SQAlignHCenter) 149 | frame.origin.x = (parentView.bounds.size.width / 2 - width / 2) + padding.left - padding.right; 150 | 151 | if (alignment & SQAlignVCenter) 152 | frame.origin.y = (parentView.bounds.size.height / 2 - height / 2) + padding.top - padding.bottom; 153 | 154 | if (alignment & SQAlignExactHCenter) 155 | frame.origin.x = (parentView.bounds.size.width / 2 - width / 2); 156 | 157 | if (alignment & SQAlignExactVCenter) 158 | frame.origin.y = (parentView.bounds.size.height / 2 - height / 2); 159 | 160 | if (alignment & SQAlignTop) 161 | frame.origin.y = padding.top; 162 | 163 | if (alignment & SQAlignBottom) 164 | frame.origin.y = parentView.bounds.size.height - height - padding.bottom; 165 | 166 | if (alignment & SQAlignExactTop) 167 | frame.origin.y = 0; 168 | 169 | if (alignment & SQAlignExactBottom) 170 | frame.origin.y = parentView.bounds.size.height - height; 171 | 172 | [view setFrame:frame]; 173 | return view; 174 | } 175 | 176 | // Layout a view relative to a peer 177 | + (UIView*) layoutView:(UIView *) view relativeToPeerView:(UIView*) relativeView 178 | placement:(SQPlace) placement alignment:(SQAlign) alignment 179 | withWidth:(CGFloat) width withHeight:(CGFloat) height 180 | withPadding:(SQPadding) padding; 181 | { 182 | CGRect frame = [view frame]; 183 | 184 | // Placement 185 | if (placement & SQPlaceOnLeft) 186 | frame.origin.x = relativeView.frame.origin.x - width - padding.right; 187 | 188 | if (placement & SQPlaceOnRight) 189 | frame.origin.x = relativeView.frame.origin.x + relativeView.frame.size.width + padding.left; 190 | 191 | if (placement & SQPlaceAbove) 192 | frame.origin.y = relativeView.frame.origin.y - height - padding.bottom; 193 | 194 | if (placement & SQPlaceBelow) 195 | frame.origin.y = relativeView.frame.origin.y + relativeView.frame.size.height + padding.top; 196 | 197 | // Alignment 198 | if (alignment & SQAlignLeft) 199 | frame.origin.x = relativeView.frame.origin.x + padding.left; 200 | 201 | if (alignment & SQAlignRight) 202 | frame.origin.x = relativeView.frame.origin.x + relativeView.frame.size.width - width - padding.right; 203 | 204 | if (alignment & SQAlignExactLeft) 205 | frame.origin.x = relativeView.frame.origin.x; 206 | 207 | if (alignment & SQAlignExactRight) 208 | frame.origin.x = relativeView.frame.origin.x + relativeView.frame.size.width - width; 209 | 210 | if (alignment & SQAlignHCenter) 211 | frame.origin.x = (relativeView.frame.origin.x + relativeView.frame.size.width / 2 - width / 2) + padding.left - padding.right; 212 | 213 | if (alignment & SQAlignVCenter) 214 | frame.origin.y = (relativeView.frame.origin.y + relativeView.frame.size.height / 2 - height / 2) + padding.left - padding.bottom; 215 | 216 | if (alignment & SQAlignExactHCenter) 217 | frame.origin.x = (relativeView.frame.origin.x + relativeView.frame.size.width / 2 - width / 2); 218 | 219 | if (alignment & SQAlignExactVCenter) 220 | frame.origin.y = (relativeView.frame.origin.y + relativeView.frame.size.height / 2 - height / 2); 221 | 222 | if (alignment & SQAlignTop) 223 | frame.origin.y = relativeView.frame.origin.y + padding.top; 224 | 225 | if (alignment & SQAlignBottom) 226 | frame.origin.y = relativeView.frame.origin.y + relativeView.frame.size.height - height - padding.bottom; 227 | 228 | if (alignment & SQAlignExactTop) 229 | frame.origin.y = relativeView.frame.origin.y; 230 | 231 | if (alignment & SQAlignExactBottom) 232 | frame.origin.y = relativeView.frame.origin.y + relativeView.frame.size.height - height; 233 | 234 | [view setFrame:frame]; 235 | return view; 236 | } 237 | 238 | 239 | + (void)resizeUILabel:(UILabel *) label constrainedToTotalSize:(CGSize) size 240 | { 241 | CGRect labelFrame = [label frame]; 242 | CGSize labelTextSize = [[label text] sizeWithFont:[label font] constrainedToSize:size lineBreakMode:[label lineBreakMode]]; 243 | 244 | [label setFrame:CGRectMake(labelFrame.origin.x, labelFrame.origin.y, labelTextSize.width, labelTextSize.height)]; 245 | } 246 | 247 | @end -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Modules/Controllers/MKViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MKViewController.h 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 21/07/13. 6 | // Copyright (c) 2013 Morgan Kennedy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MKViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Modules/Controllers/MKViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKViewController.m 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 21/07/13. 6 | // Copyright (c) 2013 Morgan Kennedy. All rights reserved. 7 | // 8 | 9 | #import "MKViewController.h" 10 | #import "MKView.h" 11 | 12 | #define mkView ((MKView *) [self view]) 13 | 14 | @interface MKViewController () 15 | 16 | @end 17 | 18 | @implementation MKViewController 19 | 20 | #pragma mark - 21 | #pragma mark - View Lifecycle 22 | 23 | - (void)viewDidLoad 24 | { 25 | [super viewDidLoad]; 26 | 27 | self.view = [[MKView alloc] initWithFrame:self.view.frame]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Modules/Views/MKView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MKView.h 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 21/07/13. 6 | // Copyright (c) 2013 Morgan Kennedy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MKParallaxView.h" 11 | 12 | @interface MKView : UIView 13 | 14 | /** 15 | Test 1 Parallax View using a normal image 16 | */ 17 | @property (nonatomic, strong) MKParallaxView *parallaxView1; 18 | 19 | /** 20 | Test 2 Parallax View using a background repeat pattern 21 | */ 22 | @property (nonatomic, strong) MKParallaxView *parallaxView2; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Modules/Views/MKView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKView.m 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 21/07/13. 6 | // Copyright (c) 2013 Morgan Kennedy. All rights reserved. 7 | // 8 | 9 | #import "MKView.h" 10 | #import "SQLayout.h" 11 | 12 | @implementation MKView 13 | 14 | - (id)initWithFrame:(CGRect)frame 15 | { 16 | self = [super initWithFrame:frame]; 17 | 18 | if (self) { 19 | _parallaxView1 = [[MKParallaxView alloc] initWithFrame:CGRectZero]; 20 | _parallaxView1.backgroundImage = [UIImage imageNamed:@"blue-dots.jpg"]; 21 | 22 | _parallaxView2 = [[MKParallaxView alloc] initWithFrame:CGRectZero]; 23 | _parallaxView2.backgroundColor = [UIColor colorWithPatternImage: 24 | [UIImage imageNamed:@"NSTexturedFullScreenBackgroundColor.png"]]; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (void)layoutSubviews 31 | { 32 | [super layoutSubviews]; 33 | 34 | UIViewController *orientationController = [[UIViewController alloc] init]; 35 | 36 | CGFloat tempWidth = self.frame.size.width; 37 | CGFloat tempHeight = self.frame.size.height; 38 | 39 | if ((orientationController.interfaceOrientation == UIInterfaceOrientationLandscapeRight) || 40 | (orientationController.interfaceOrientation == UIInterfaceOrientationLandscapeLeft)) 41 | { 42 | if (self.frame.size.width < self.frame.size.height) 43 | { 44 | tempWidth = self.frame.size.height; 45 | tempHeight = self.frame.size.width; 46 | } 47 | 48 | [SQLayout layoutView:self.parallaxView1 49 | relativeToView:self 50 | placement:SQPlaceWithin 51 | alignment:SQAlignTop | SQAlignLeft 52 | withWidth:tempWidth/2.0f 53 | withHeight:tempHeight 54 | withPadding:SQPaddingZero]; 55 | 56 | [SQLayout layoutView:self.parallaxView2 57 | relativeToView:self.parallaxView1 58 | placement:SQPlaceOnRight 59 | alignment:SQAlignTop 60 | withWidth:tempWidth/2.0f 61 | withHeight:tempHeight 62 | withPadding:SQPaddingZero]; 63 | } 64 | else 65 | { 66 | if (self.frame.size.width > self.frame.size.height) 67 | { 68 | tempWidth = self.frame.size.height; 69 | tempHeight = self.frame.size.width; 70 | } 71 | 72 | [SQLayout layoutView:self.parallaxView1 73 | relativeToView:self 74 | placement:SQPlaceWithin 75 | alignment:SQAlignTop | SQAlignLeft 76 | withWidth:tempWidth 77 | withHeight:tempHeight/2.0f 78 | withPadding:SQPaddingZero]; 79 | 80 | [SQLayout layoutView:self.parallaxView2 81 | relativeToView:self.parallaxView1 82 | placement:SQPlaceBelow 83 | alignment:SQAlignLeft 84 | withWidth:tempWidth 85 | withHeight:tempHeight/2.0f 86 | withPadding:SQPaddingZero]; 87 | } 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgan-Kennedy/MKParallaxView/e8e52db3e67b30cdeb778bd9961a126030f5bc01/MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/Default-568h@2x.png -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgan-Kennedy/MKParallaxView/e8e52db3e67b30cdeb778bd9961a126030f5bc01/MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/Default.png -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgan-Kennedy/MKParallaxView/e8e52db3e67b30cdeb778bd9961a126030f5bc01/MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/Default@2x.png -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/NSTexturedFullScreenBackgroundColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgan-Kennedy/MKParallaxView/e8e52db3e67b30cdeb778bd9961a126030f5bc01/MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/NSTexturedFullScreenBackgroundColor.png -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/blue-dots.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgan-Kennedy/MKParallaxView/e8e52db3e67b30cdeb778bd9961a126030f5bc01/MKParallaxViewDemo/MKParallaxViewDemo/Resources/Images/blue-dots.jpg -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Supporting Files/MKDynamicViewDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.MorganKennedy.MKParallaxView 13 | CFBundleInfoDictionaryVersion 14 | 6.1 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 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Supporting Files/MKParallaxViewDemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'MKParallaxViewDemo' target in the 'MKParallaxViewDemo' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iOS SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Supporting Files/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /MKParallaxViewDemo/MKParallaxViewDemo/Supporting Files/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MKParallaxViewDemo 4 | // 5 | // Created by Morgan Kennedy on 21/07/13. 6 | // Copyright (c) 2013 Morgan Kennedy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "MKAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([MKAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MKParallaxView 2 | ============== 3 | 4 | MKParallaxView is an easy to use framework used to create the IOS 7 Parallax Effect (Dynamic Background) on any of your apps! 5 | 6 | Treat it just like a UIImageView and by simply assigning an image to it with 1 line you have the exact same effect for the background of your app. 7 | 8 | UPDATES: 9 | - Storyboard Friendly (Thanks Kinwo) 10 | - Overridden Getters for parameters (Thanks Augard) 11 | 12 | MKParallaxView is now a CocoaPod! so jump to http://cocoapods.org/ to get it that way :) 13 | 14 | Important note: this framework uses the device's gyro, so it will look just like a normal background in simulators. Try the demo on a device instead! 15 | 16 | To start go to Project -> Target -> Build Phases -> Link Binary With Libraries and add CoreMotion.framework 17 | 18 | In the view or view controller (or prefix): 19 | 20 | #import "MKParallaxView.h" 21 | 22 | To create the parallax view with a basic background image do the following: 23 | 24 | MKParallaxView *basicBackground = [[MKParallaxView alloc] initWithFrame:self.frame]; 25 | basicBackground.backgroundImage = [UIImage imageNamed:@"backgroundImage.png"]; 26 | 27 | To create the parallax view with a repeat background image do the following: 28 | 29 | MKParallaxView *repeatBackgound = [[MKParallaxView alloc] initWithFrame:self.frame]; 30 | repeatBackgound.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"backgroundRepeatableImage.png"]]; 31 | 32 | The animation defaults at 60 frames per second (fps) which is really smooth, but if you want to bring it down to say 30 fps, just do the following on each MKParallaxView you have: 33 | 34 | basicBackground.updateRate = 30; 35 | 36 | I hope you enjoy this framework. Please star it above; and if your iTunes app uses it, please add it to the list on the wiki along with an iTunes link. 37 | 38 | Thank you, 39 | 40 | Kind Regards 41 | 42 | Morgan Kennedy 43 | 44 | p.s. If you want you can utilize the MKGyroManager as is: 45 | 46 | MKGyroManager 47 | ============== 48 | 49 | If you want to use the "roll" "pitch" "yaw" values that the gyro manager (singleton) spits out 60 times a second anywhere else in your app you can by doing the following: 50 | 51 | #import "MKGyroManager.h"
52 | @interface MyViewController ()< MKGyroManagerDelegate >
53 | [MKGyroManager sharedGyroManager].delegate = self;
54 | - (void)MKGyroManagerUpdatedRoll:(CGFloat)roll Pitch:(CGFloat)pitch Yaw:(CGFloat)yaw
55 | 56 | There's also a NSNotification that you can listen to if you prefer with the values in the notification.userInfo
57 | MKGyroManagerUpdateAnglesNotification 58 | 59 | Or you can just observe the latestValue of a specific attribute like so:
60 | CGFloat roll = [[MKGyroManager sharedGyroManager] roll]; 61 | --------------------------------------------------------------------------------