├── .DS_Store ├── CADemo.xcodeproj └── project.pbxproj ├── CADemo ├── BasicAnimationsViewController.h ├── BasicAnimationsViewController.m ├── BasicAnimationsViewController.xib ├── CADemo-Info.plist ├── CADemo-Prefix.pch ├── CADemoAppDelegate.h ├── CADemoAppDelegate.m ├── CardLayoutView.h ├── CardLayoutView.m ├── CardLayoutViewController.h ├── CardLayoutViewController.m ├── CardLayoutViewController.xib ├── DemoCardView.h ├── DemoCardView.m ├── DismissControl.h ├── DismissControl.m ├── GraphicsUtils.h ├── GraphicsUtils.m ├── GroupAnimationViewController.h ├── GroupAnimationViewController.m ├── GroupAnimationViewController.xib ├── ImplicitAnimationsViewController.h ├── ImplicitAnimationsViewController.m ├── ImplicitAnimationsViewController.xib ├── KeyPathAnimationView.h ├── KeyPathAnimationView.m ├── KeyPathAnimationViewController.h ├── KeyPathAnimationViewController.m ├── KeyPathAnimationViewController.xib ├── MagnifierView.h ├── MagnifierView.m ├── MagnifierViewController.h ├── MagnifierViewController.m ├── Media │ ├── .DS_Store │ ├── Browser.png │ ├── Calculator.png │ ├── Calendar.png │ ├── Chat.png │ ├── Clock.png │ ├── Graph.png │ ├── Maps.png │ ├── Notes.png │ ├── Phone.png │ ├── Settings.png │ ├── Weather.png │ ├── Wheel.png │ ├── glacier.jpg │ ├── iPod.png │ ├── moab.jpg │ ├── paris.JPG │ ├── rainbow.jpg │ ├── redrock.jpg │ ├── rickroll.mp4 │ └── sydney.jpg ├── MoviePlayerViewController.h ├── MoviePlayerViewController.m ├── MoviePlayerViewController.xib ├── SublayerTransformView.h ├── SublayerTransformView.m ├── TransitionDirectionViewController.h ├── TransitionDirectionViewController.m ├── TransitionTypeViewController.h ├── TransitionTypeViewController.m ├── TransitionViewController.h ├── TransitionViewController.m ├── TransitionViewController.xib ├── en.lproj │ ├── InfoPlist.strings │ └── MainWindow.xib └── main.m ├── CoreAnimationForBoulderIOS.pdf └── README /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/.DS_Store -------------------------------------------------------------------------------- /CADemo/BasicAnimationsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BasicAnimationsViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/25/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | #import "DemoCardView.h" 33 | 34 | @interface BasicAnimationsViewController : UIViewController { 35 | 36 | } 37 | 38 | - (IBAction)startWobbling:(id)sender; 39 | - (IBAction)startPulsing:(id)sender; 40 | - (IBAction)stop:(id)sender; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /CADemo/BasicAnimationsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BasicAnimationsViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/25/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import "BasicAnimationsViewController.h" 31 | 32 | #import 33 | 34 | @interface BasicAnimationsViewController () 35 | 36 | @property(nonatomic, retain) NSMutableArray *layers; 37 | 38 | @end 39 | @implementation BasicAnimationsViewController 40 | 41 | @synthesize layers = layers_; 42 | 43 | - (id)initWithFrame:(CGRect)frame { 44 | self = [super initWithNibName:nil bundle:nil]; 45 | if (self) { 46 | self.view.frame = frame; 47 | layers_ = [[NSMutableArray alloc] init]; 48 | CGRect bounds = self.view.bounds; 49 | NSArray *images = [NSArray arrayWithObjects: 50 | @"Browser.png", @"Calculator.png", @"Calendar.png", @"Chat.png", 51 | @"Clock.png", @"Graph.png", @"iPod.png", @"Maps.png", @"Notes.png", 52 | @"Phone.png", @"Settings.png", @"Weather.png", @"Wheel.png", nil]; 53 | NSInteger imageCount = [images count]; 54 | NSInteger rows = 7; 55 | NSInteger columns = 6; 56 | CGFloat inset = 60; 57 | CGFloat space = 50; 58 | CGFloat width = (bounds.size.width - (inset * 2) - (space * (columns - 1))) / columns; 59 | 60 | CALayer *mainLayer = self.view.layer; 61 | mainLayer.backgroundColor = [UIColor blackColor].CGColor; 62 | 63 | int imageIndex = 0; 64 | for (int r = 0; r < rows; r++) { 65 | for (int c = 0; c < columns; c++) { 66 | CALayer *layer = [CALayer layer]; 67 | layer.contents = (id)[UIImage imageNamed:[images objectAtIndex:imageIndex]].CGImage; 68 | layer.bounds = CGRectMake(0, 0, width, width); 69 | layer.edgeAntialiasingMask = kCALayerTopEdge|kCALayerBottomEdge|kCALayerLeftEdge|kCALayerRightEdge; 70 | [mainLayer addSublayer:layer]; 71 | [layers_ addObject:layer]; 72 | layer.position = CGPointMake(inset + c * (space + width) + width * 0.5, 73 | 44 + inset + r * (space + width) + width * 0.5); 74 | imageIndex = ++imageIndex % imageCount; 75 | } 76 | } 77 | 78 | } 79 | return self; 80 | } 81 | 82 | - (void)dealloc { 83 | [layers_ release]; 84 | [super dealloc]; 85 | } 86 | 87 | #pragma mark - View lifecycle 88 | 89 | - (void)viewDidLoad{ 90 | [super viewDidLoad]; 91 | 92 | } 93 | 94 | - (void)viewDidUnload { 95 | [layers_ makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; 96 | [super viewDidUnload]; 97 | } 98 | 99 | - (IBAction)startWobbling:(id)sender { 100 | for (CALayer *layer in layers_) { 101 | [layer removeAllAnimations]; 102 | CABasicAnimation *wobble = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 103 | wobble.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 104 | wobble.duration = 0.1 + (rand() % 10) * 0.005; 105 | wobble.repeatCount = HUGE_VALF; 106 | wobble.autoreverses = YES; 107 | wobble.fromValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(5)]; 108 | wobble.toValue = [NSNumber numberWithFloat:-DEGREES_TO_RADIANS(5)]; 109 | [layer addAnimation:wobble forKey:@"transform.rotation.z"]; 110 | } 111 | } 112 | 113 | - (IBAction)startPulsing:(id)sender { 114 | for (CALayer *layer in layers_) { 115 | [layer removeAllAnimations]; 116 | CABasicAnimation *pulse = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 117 | pulse.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 118 | pulse.duration = 0.5 + (rand() % 10) * 0.05; 119 | pulse.repeatCount = HUGE_VALF; 120 | pulse.autoreverses = YES; 121 | pulse.fromValue = [NSNumber numberWithFloat:.8]; 122 | pulse.toValue = [NSNumber numberWithFloat:1.5]; 123 | [layer addAnimation:pulse forKey:@"transform.scale"]; 124 | } 125 | } 126 | 127 | - (IBAction)stop:(id)sender { 128 | for (CALayer *layer in layers_) { 129 | [layer removeAllAnimations]; 130 | } 131 | } 132 | 133 | #pragma mark - 134 | #pragma mark DemoCardSubview methods 135 | 136 | - (NSString *)displayName { 137 | return @"Basic Animations"; 138 | } 139 | 140 | - (void)startAnimating { 141 | [self startWobbling:self]; 142 | } 143 | 144 | - (void)stopAnimating { 145 | [self stop:self]; 146 | } 147 | 148 | @end 149 | -------------------------------------------------------------------------------- /CADemo/BasicAnimationsViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 11A511 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 534 12 | 13 | 14 | YES 15 | IBUIBarButtonItem 16 | IBUIToolbar 17 | IBUIView 18 | IBProxyObject 19 | 20 | 21 | YES 22 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 23 | 24 | 25 | YES 26 | 27 | YES 28 | 29 | 30 | 31 | 32 | YES 33 | 34 | IBFilesOwner 35 | IBIPadFramework 36 | 37 | 38 | IBFirstResponder 39 | IBIPadFramework 40 | 41 | 42 | 43 | 292 44 | 45 | YES 46 | 47 | 48 | 290 49 | {768, 44} 50 | 51 | 52 | 53 | _NS:345 54 | NO 55 | NO 56 | IBIPadFramework 57 | 58 | YES 59 | 60 | IBIPadFramework 61 | 62 | 5 63 | 64 | 65 | Animation Type: 66 | IBIPadFramework 67 | 68 | 69 | 70 | Wobble 71 | IBIPadFramework 72 | 1 73 | 74 | 75 | 76 | Pulse 77 | IBIPadFramework 78 | 1 79 | 80 | 81 | 82 | IBIPadFramework 83 | 1 84 | 85 | 18 86 | 87 | 88 | 89 | 90 | {{0, 20}, {768, 1004}} 91 | 92 | 93 | 94 | 95 | 3 96 | MQA 97 | 98 | 2 99 | 100 | 101 | NO 102 | 103 | 2 104 | 105 | IBIPadFramework 106 | 107 | 108 | 109 | 110 | YES 111 | 112 | 113 | view 114 | 115 | 116 | 117 | 3 118 | 119 | 120 | 121 | startWobbling: 122 | 123 | 124 | 125 | 9 126 | 127 | 128 | 129 | startPulsing: 130 | 131 | 132 | 133 | 11 134 | 135 | 136 | 137 | stop: 138 | 139 | 140 | 141 | 15 142 | 143 | 144 | 145 | 146 | YES 147 | 148 | 0 149 | 150 | 151 | 152 | 153 | 154 | -1 155 | 156 | 157 | File's Owner 158 | 159 | 160 | -2 161 | 162 | 163 | 164 | 165 | 2 166 | 167 | 168 | YES 169 | 170 | 171 | 172 | 173 | 174 | 4 175 | 176 | 177 | YES 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 5 188 | 189 | 190 | 191 | 192 | 6 193 | 194 | 195 | 196 | 197 | 7 198 | 199 | 200 | 201 | 202 | 8 203 | 204 | 205 | 206 | 207 | 12 208 | 209 | 210 | 211 | 212 | 213 | 214 | YES 215 | 216 | YES 217 | -1.CustomClassName 218 | -1.IBPluginDependency 219 | -2.CustomClassName 220 | -2.IBPluginDependency 221 | 12.IBPluginDependency 222 | 2.IBPluginDependency 223 | 4.IBPluginDependency 224 | 5.IBPluginDependency 225 | 6.IBPluginDependency 226 | 7.IBPluginDependency 227 | 8.IBPluginDependency 228 | 229 | 230 | YES 231 | BasicAnimationsViewController 232 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 233 | UIResponder 234 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 235 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 236 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 237 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 238 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 239 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 240 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 241 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 242 | 243 | 244 | 245 | YES 246 | 247 | 248 | 249 | 250 | 251 | YES 252 | 253 | 254 | 255 | 256 | 15 257 | 258 | 259 | 260 | YES 261 | 262 | BasicAnimationsViewController 263 | UIViewController 264 | 265 | YES 266 | 267 | YES 268 | startPulsing: 269 | startWobbling: 270 | stop: 271 | 272 | 273 | YES 274 | id 275 | id 276 | id 277 | 278 | 279 | 280 | YES 281 | 282 | YES 283 | startPulsing: 284 | startWobbling: 285 | stop: 286 | 287 | 288 | YES 289 | 290 | startPulsing: 291 | id 292 | 293 | 294 | startWobbling: 295 | id 296 | 297 | 298 | stop: 299 | id 300 | 301 | 302 | 303 | 304 | IBProjectSource 305 | ./Classes/BasicAnimationsViewController.h 306 | 307 | 308 | 309 | 310 | 0 311 | IBIPadFramework 312 | 313 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 314 | 315 | 316 | YES 317 | 3 318 | 534 319 | 320 | 321 | -------------------------------------------------------------------------------- /CADemo/CADemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | us.blueiris.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | NSMainNibFile 30 | MainWindow 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /CADemo/CADemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'CADemo' target in the 'CADemo' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iPhone SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #import 15 | #endif 16 | 17 | #define DEGREES_TO_RADIANS(d) (d * M_PI / 180) 18 | 19 | static CATransform3D CATransform3DMakePerspective(CGFloat z) { 20 | CATransform3D t = CATransform3DIdentity; 21 | t.m34 = - 1.0 / z; 22 | return t; 23 | } -------------------------------------------------------------------------------- /CADemo/CADemoAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CADemoAppDelegate.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | @interface CADemoAppDelegate : NSObject 33 | 34 | @property (nonatomic, retain) IBOutlet UIWindow *window; 35 | 36 | @property (nonatomic, retain) IBOutlet UINavigationController *navigationController; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /CADemo/CADemoAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CADemoAppDelegate.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 "CADemoAppDelegate.h" 30 | 31 | @implementation CADemoAppDelegate 32 | 33 | @synthesize window = _window; 34 | @synthesize navigationController = _navigationController; 35 | 36 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 37 | { 38 | // Override point for customization after application launch. 39 | // Add the navigation controller's view to the window and display. 40 | self.window.rootViewController = self.navigationController; 41 | [self.window makeKeyAndVisible]; 42 | return YES; 43 | } 44 | 45 | - (void)applicationWillResignActive:(UIApplication *)application 46 | { 47 | /* 48 | 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. 49 | 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. 50 | */ 51 | } 52 | 53 | - (void)applicationDidEnterBackground:(UIApplication *)application 54 | { 55 | /* 56 | 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. 57 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 58 | */ 59 | } 60 | 61 | - (void)applicationWillEnterForeground:(UIApplication *)application 62 | { 63 | /* 64 | 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. 65 | */ 66 | } 67 | 68 | - (void)applicationDidBecomeActive:(UIApplication *)application 69 | { 70 | /* 71 | 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. 72 | */ 73 | } 74 | 75 | - (void)applicationWillTerminate:(UIApplication *)application 76 | { 77 | /* 78 | Called when the application is about to terminate. 79 | Save data if appropriate. 80 | See also applicationDidEnterBackground:. 81 | */ 82 | } 83 | 84 | - (void)dealloc 85 | { 86 | [_window release]; 87 | [_navigationController release]; 88 | [super dealloc]; 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /CADemo/CardLayoutView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CardLayoutView.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | @protocol CardLayoutDataSource 33 | 34 | - (NSString *)observableKeyPath; 35 | 36 | @end 37 | 38 | typedef enum { 39 | kCardLayoutGrid, 40 | kCardLayoutCircle, 41 | kCardLayoutRandom 42 | } CardLayout; 43 | 44 | @interface CardLayoutView : UIView 45 | 46 | @property(nonatomic, assign) IBOutlet id dataSource; 47 | @property(nonatomic, readwrite) CardLayout layout; 48 | @property(nonatomic, assign) CGSize inset; 49 | @property(nonatomic, assign) CGSize spacing; 50 | @property(nonatomic, assign) NSUInteger rows; 51 | @property(nonatomic, assign) NSUInteger columns; 52 | @property(nonatomic, assign) NSTimeInterval animationDuration; 53 | 54 | 55 | @end 56 | 57 | -------------------------------------------------------------------------------- /CADemo/CardLayoutView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CardLayoutView.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import "CardLayoutView.h" 31 | #import "DemoCardView.h" 32 | #import "GraphicsUtils.h" 33 | 34 | @interface CardLayoutView () 35 | 36 | @property CGSize subviewSize; 37 | 38 | @end 39 | 40 | @implementation CardLayoutView 41 | 42 | @synthesize dataSource = dataSource_; 43 | @synthesize layout = layout_; 44 | @synthesize inset = inset_; 45 | @synthesize spacing = spacing_; 46 | @synthesize rows = rows_; 47 | @synthesize columns = columns_; 48 | @synthesize animationDuration = animationDuration_; 49 | @synthesize subviewSize = subviewSize_; 50 | 51 | - (void)awakeFromNib { 52 | [self.dataSource addObserver:self 53 | forKeyPath:[self.dataSource observableKeyPath] 54 | options:NSKeyValueObservingOptionNew 55 | context:NULL]; 56 | self.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1.0]; 57 | } 58 | 59 | 60 | - (void)dealloc { 61 | [self.dataSource removeObserver:self forKeyPath:[self.dataSource observableKeyPath]]; 62 | [super dealloc]; 63 | } 64 | 65 | #pragma mark - 66 | #pragma mark Data Source methods 67 | 68 | - (void)observeValueForKeyPath:(NSString *)keyPath 69 | ofObject:(id)object 70 | change:(NSDictionary *)change 71 | context:(void *)context { 72 | [self setNeedsLayout]; 73 | } 74 | 75 | - (NSArray *)viewsFromDataSource { 76 | return [self.dataSource valueForKeyPath:[self.dataSource observableKeyPath]]; 77 | } 78 | 79 | - (void)removeUnneededSubviews { 80 | NSArray *views = [self viewsFromDataSource]; 81 | for (UIView *view in self.subviews) { 82 | if (![views containsObject:view]) { 83 | [view removeFromSuperview]; 84 | } 85 | } 86 | } 87 | 88 | - (void)updateCircle { 89 | CGRect bounds = self.bounds; 90 | NSUInteger index = 0; 91 | 92 | [UIView beginAnimations:@"circleView" context:NULL]; 93 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 94 | [UIView setAnimationDuration:animationDuration_]; 95 | 96 | CGPoint center = [GraphicsUtils centerOfRect:bounds]; 97 | CGSize size = bounds.size; 98 | CGFloat offset = 0.5 * MIN(size.width - subviewSize_.width - inset_.width, 99 | size.height - subviewSize_.height - inset_.height); 100 | 101 | // This is pure laziness. I should figure out the correct size based on the screen size. 102 | subviewSize_ = CGSizeMake(175, 175); 103 | 104 | NSArray *newViews = [self viewsFromDataSource]; 105 | CGFloat angle = 2 * M_PI / [newViews count]; 106 | for (DemoCardView *view in newViews) { 107 | if (!view.isZoomedIn) { 108 | CGFloat xOffset = offset * cosf(angle * index); 109 | CGFloat yOffset = offset * sinf(angle * index); 110 | 111 | view.center = CGPointMake(center.x + xOffset, center.y + yOffset); 112 | CGRect newBounds = CGRectMake(0, 0, subviewSize_.width, subviewSize_.height); 113 | CGFloat scale = [GraphicsUtils scaleForSize:view.bounds.size inRect:newBounds]; 114 | CGAffineTransform scaleAndRotate = 115 | CGAffineTransformRotate(CGAffineTransformMakeScale(scale, scale), angle * index + M_PI_2); 116 | view.transform = scaleAndRotate; 117 | 118 | if (![self.subviews containsObject:view]) { 119 | [self addSubview:view]; 120 | } 121 | } 122 | index++; 123 | } 124 | [UIView commitAnimations]; 125 | } 126 | 127 | - (void)updateGrid { 128 | CGRect bounds = self.bounds; 129 | 130 | subviewSize_.width = (bounds.size.width - (2 * inset_.width) - ((columns_ - 1) * spacing_.width)) 131 | / columns_; 132 | subviewSize_.height = (bounds.size.height - (2 * inset_.height) - ((rows_ - 1) * spacing_.height)) 133 | / rows_; 134 | NSUInteger index = 0; 135 | 136 | [UIView beginAnimations:@"gridView" context:NULL]; 137 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 138 | [UIView setAnimationDuration:animationDuration_]; 139 | 140 | NSArray *newViews = [self viewsFromDataSource]; 141 | for (DemoCardView *view in newViews) { 142 | if (!view.isZoomedIn) { 143 | NSUInteger row = index / columns_; 144 | NSUInteger col = index % columns_; 145 | row = row % rows_; 146 | 147 | // Compute the new rect 148 | CGRect newFrame = CGRectMake( 149 | inset_.width + col * (subviewSize_.width + spacing_.width), 150 | inset_.height + row * (subviewSize_.height + spacing_.height), 151 | subviewSize_.width, subviewSize_.height); 152 | 153 | // Use the transform to resize the view. Move it by setting the center. 154 | CGFloat scale = [GraphicsUtils scaleForSize:self.bounds.size inRect:newFrame]; 155 | view.center = [GraphicsUtils centerOfRect:newFrame]; 156 | view.transform = CGAffineTransformScale(CGAffineTransformIdentity, scale, scale); 157 | 158 | if (![self.subviews containsObject:view]) { 159 | [self addSubview:view]; 160 | } 161 | } 162 | index++; 163 | } 164 | 165 | [UIView commitAnimations]; 166 | 167 | } 168 | 169 | - (void)layoutSubviews { 170 | [self removeUnneededSubviews]; 171 | 172 | if (layout_ == kCardLayoutGrid) { 173 | [self updateGrid]; 174 | } else if (layout_ == kCardLayoutCircle) { 175 | [self updateCircle]; 176 | } 177 | } 178 | @end 179 | -------------------------------------------------------------------------------- /CADemo/CardLayoutViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CardLayoutViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | #import "CardLayoutView.h" 33 | 34 | @interface CardLayoutViewController : UIViewController { 35 | 36 | } 37 | @property(nonatomic, retain) IBOutlet CardLayoutView *cardLayoutView; 38 | @property(nonatomic, readonly) NSMutableArray *cardViews; 39 | 40 | - (NSString *)observableKeyPath; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /CADemo/CardLayoutViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CardLayoutViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import "CardLayoutViewController.h" 31 | 32 | #import "DemoCardView.h" 33 | #import "BasicAnimationsViewController.h" 34 | #import "GroupAnimationViewController.h" 35 | #import "ImplicitAnimationsViewController.h" 36 | #import "KeyPathAnimationViewController.h" 37 | #import "MagnifierViewController.h" 38 | #import "MoviePlayerViewController.h" 39 | #import "SublayerTransformView.h" 40 | #import "TransitionViewController.h" 41 | 42 | @interface CardLayoutViewController () 43 | 44 | @property(nonatomic, retain) UISegmentedControl *layoutControl; 45 | @property(nonatomic, retain) UIPopoverController *settingsPopover; 46 | @property(nonatomic, retain) KeyPathAnimationViewController *keypathDemo; 47 | @property(nonatomic, retain) ImplicitAnimationsViewController *implicitDemo; 48 | 49 | - (void)setParametersForOrientation:(UIInterfaceOrientation)orientation; 50 | @end 51 | 52 | @implementation CardLayoutViewController 53 | 54 | @synthesize cardViews = cardViews_; 55 | @synthesize cardLayoutView = cardLayoutView_; 56 | @synthesize layoutControl = layoutControl_; 57 | @synthesize settingsPopover = settingsPopover_; 58 | @synthesize keypathDemo = keypathDemo_; 59 | @synthesize implicitDemo = implicitDemo_; 60 | 61 | - (void)dealloc { 62 | [cardViews_ release]; 63 | [layoutControl_ release]; 64 | [settingsPopover_ release]; 65 | [keypathDemo_ release]; 66 | [super dealloc]; 67 | } 68 | 69 | #pragma mark - View lifecycle 70 | 71 | - (void)viewDidLoad { 72 | [super viewDidLoad]; 73 | [self setParametersForOrientation:self.interfaceOrientation]; 74 | cardViews_ = [[NSMutableArray alloc] init]; 75 | cardLayoutView_.inset = CGSizeMake(30, 30); 76 | cardLayoutView_.spacing = CGSizeMake(30, 30); 77 | cardLayoutView_.animationDuration = 0.4; 78 | 79 | layoutControl_ = [[UISegmentedControl alloc] initWithItems: 80 | [NSArray arrayWithObjects:@"Grid", @"Circle", nil]]; 81 | layoutControl_.segmentedControlStyle = UISegmentedControlStyleBar; 82 | layoutControl_.selectedSegmentIndex = 0; 83 | [layoutControl_ addTarget:self 84 | action:@selector(updateLayout) 85 | forControlEvents:UIControlEventValueChanged]; 86 | 87 | UIBarButtonItem *layoutItem = [[[UIBarButtonItem alloc] initWithCustomView:layoutControl_] 88 | autorelease]; 89 | 90 | self.navigationItem.rightBarButtonItem = layoutItem; 91 | 92 | // Every view is always sized to fit the screen. If it's shrunk, it's due to the view transform. 93 | CGRect layoutFrame = cardLayoutView_.frame; 94 | CGRect cardFrame = CGRectMake(0, 0, layoutFrame.size.width - 40, layoutFrame.size.height - 148); 95 | for (int i = 0; i < 8; i++) { 96 | DemoCardView *cardView = [[[DemoCardView alloc] initWithFrame:cardFrame] autorelease]; 97 | cardView.parentController = self; 98 | UIView *placeholder = [[UIView alloc] initWithFrame:cardFrame]; 99 | placeholder.backgroundColor = [UIColor colorWithHue:.6 saturation:.3 brightness:.6 alpha:1.0]; 100 | cardView.demoView = (id)placeholder; 101 | [cardViews_ addObject:cardView]; 102 | } 103 | // 0 is implicit animations. 104 | implicitDemo_ = [[ImplicitAnimationsViewController alloc] initWithFrame:cardFrame]; 105 | ((DemoCardView *)[cardViews_ objectAtIndex:0]).demoView = implicitDemo_; 106 | 107 | // 1 is basic demo. 108 | ((DemoCardView *)[cardViews_ objectAtIndex:1]).demoView = 109 | [[BasicAnimationsViewController alloc] initWithFrame:cardFrame]; 110 | 111 | // 2 is keyframe demo. 112 | keypathDemo_ = [[KeyPathAnimationViewController alloc] initWithFrame:cardFrame]; 113 | ((DemoCardView *)[cardViews_ objectAtIndex:2]).demoView = keypathDemo_; 114 | 115 | // 3 is 3D/Sublayer 116 | ((DemoCardView *)[cardViews_ objectAtIndex:3]).demoView = 117 | [[SublayerTransformView alloc] initWithFrame:cardFrame]; 118 | 119 | // 4 is grouped/composite. 120 | ((DemoCardView *)[cardViews_ objectAtIndex:4]).demoView = 121 | [[GroupAnimationViewController alloc] initWithFrame:cardFrame]; 122 | 123 | // 3 is transitions. 124 | ((DemoCardView *)[cardViews_ objectAtIndex:5]).demoView = 125 | [[TransitionViewController alloc] initWithFrame:cardFrame]; 126 | 127 | // 6 movie in a layer 128 | ((DemoCardView *)[cardViews_ objectAtIndex:6]).demoView = 129 | [[MoviePlayerViewController alloc] initWithFrame:cardFrame]; 130 | 131 | // 7 magnifier 132 | ((DemoCardView *)[cardViews_ objectAtIndex:7]).demoView = 133 | [[MagnifierViewController alloc] initWithFrame:cardFrame]; 134 | 135 | [cardLayoutView_ setNeedsLayout]; 136 | } 137 | 138 | - (void)viewDidUnload { 139 | [super viewDidUnload]; 140 | } 141 | 142 | #pragma mark - 143 | #pragma mark Interface actions 144 | 145 | - (void)updateLayout { 146 | NSInteger index = [layoutControl_ selectedSegmentIndex]; 147 | if (index == 0) { 148 | cardLayoutView_.layout = kCardLayoutGrid; 149 | } else { 150 | cardLayoutView_.layout = kCardLayoutCircle; 151 | } 152 | [cardLayoutView_ setNeedsLayout]; 153 | } 154 | 155 | #pragma mark - 156 | #pragma mark User interface rotation. 157 | 158 | - (void)setParametersForOrientation:(UIInterfaceOrientation)orientation { 159 | if (UIInterfaceOrientationIsPortrait(orientation)) { 160 | cardLayoutView_.rows = 3; 161 | cardLayoutView_.columns = 3; 162 | } else if (UIInterfaceOrientationIsLandscape(orientation)) { 163 | cardLayoutView_.rows = 3; 164 | cardLayoutView_.columns = 3; 165 | } 166 | } 167 | 168 | - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 169 | duration:(NSTimeInterval)duration { 170 | cardLayoutView_.animationDuration = duration; 171 | [self setParametersForOrientation:toInterfaceOrientation]; 172 | 173 | // TODO: Set the bounds of all the views to the new shape. 174 | 175 | [cardLayoutView_ setNeedsLayout]; 176 | } 177 | 178 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 179 | return YES; 180 | } 181 | 182 | #pragma mark CardLayoutDataSource 183 | 184 | - (NSString *)observableKeyPath { 185 | return @"cardViews"; 186 | } 187 | 188 | @end 189 | -------------------------------------------------------------------------------- /CADemo/CardLayoutViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 11A511 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 534 12 | 13 | 14 | YES 15 | IBProxyObject 16 | IBUIView 17 | 18 | 19 | YES 20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 21 | 22 | 23 | YES 24 | 25 | YES 26 | 27 | 28 | 29 | 30 | YES 31 | 32 | IBFilesOwner 33 | IBIPadFramework 34 | 35 | 36 | IBFirstResponder 37 | IBIPadFramework 38 | 39 | 40 | 41 | 292 42 | 43 | YES 44 | 45 | 46 | 274 47 | {768, 1004} 48 | 49 | 50 | _NS:195 51 | 52 | 3 53 | MQA 54 | 55 | 2 56 | 57 | 58 | IBIPadFramework 59 | 60 | 61 | {{0, 20}, {768, 1004}} 62 | 63 | 64 | 65 | 66 | 3 67 | MQA 68 | 69 | 70 | NO 71 | 72 | 2 73 | 74 | IBIPadFramework 75 | 76 | 77 | 78 | 79 | YES 80 | 81 | 82 | view 83 | 84 | 85 | 86 | 3 87 | 88 | 89 | 90 | cardLayoutView 91 | 92 | 93 | 94 | 5 95 | 96 | 97 | 98 | dataSource 99 | 100 | 101 | 102 | 6 103 | 104 | 105 | 106 | 107 | YES 108 | 109 | 0 110 | 111 | 112 | 113 | 114 | 115 | -1 116 | 117 | 118 | File's Owner 119 | 120 | 121 | -2 122 | 123 | 124 | 125 | 126 | 2 127 | 128 | 129 | YES 130 | 131 | 132 | 133 | 134 | 135 | 4 136 | 137 | 138 | View 139 | 140 | 141 | 142 | 143 | YES 144 | 145 | YES 146 | -1.CustomClassName 147 | -1.IBPluginDependency 148 | -2.CustomClassName 149 | -2.IBPluginDependency 150 | 2.IBPluginDependency 151 | 4.CustomClassName 152 | 4.IBPluginDependency 153 | 154 | 155 | YES 156 | CardLayoutViewController 157 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 158 | UIResponder 159 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 160 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 161 | CardLayoutView 162 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 163 | 164 | 165 | 166 | YES 167 | 168 | 169 | 170 | 171 | 172 | YES 173 | 174 | 175 | 176 | 177 | 6 178 | 179 | 180 | 181 | YES 182 | 183 | CardLayoutView 184 | UIView 185 | 186 | dataSource 187 | id 188 | 189 | 190 | dataSource 191 | 192 | dataSource 193 | id 194 | 195 | 196 | 197 | IBProjectSource 198 | ./Classes/CardLayoutView.h 199 | 200 | 201 | 202 | CardLayoutViewController 203 | UIViewController 204 | 205 | cardLayoutView 206 | CardLayoutView 207 | 208 | 209 | cardLayoutView 210 | 211 | cardLayoutView 212 | CardLayoutView 213 | 214 | 215 | 216 | IBProjectSource 217 | ./Classes/CardLayoutViewController.h 218 | 219 | 220 | 221 | 222 | 0 223 | IBIPadFramework 224 | 225 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 226 | 227 | 228 | YES 229 | 3 230 | 534 231 | 232 | 233 | -------------------------------------------------------------------------------- /CADemo/DemoCardView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DemoCardView.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | @class CardLayoutViewController; 33 | 34 | @protocol DemoCardSubview 35 | 36 | - (void)startAnimating; 37 | 38 | - (void)stopAnimating; 39 | 40 | @property(nonatomic, readonly) NSString *displayName; 41 | 42 | @end 43 | 44 | @interface DemoCardView : UIView 45 | 46 | @property(nonatomic, assign) CardLayoutViewController *parentController; 47 | @property(nonatomic, assign, getter = isZoomedIn) BOOL zoomedIn; 48 | @property(nonatomic, retain) id demoView; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /CADemo/DemoCardView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoCardView.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | #import "DemoCardView.h" 33 | #import "DismissControl.h" 34 | #import "GraphicsUtils.h" 35 | #import "CardLayoutViewController.h" 36 | 37 | @interface DemoCardView () 38 | 39 | @property(nonatomic, retain) UITapGestureRecognizer *tapRecognizer; 40 | @property(nonatomic, retain) DismissControl *dismissControl; 41 | @property(nonatomic, retain) UIView *actualDemoView; 42 | 43 | @end 44 | 45 | @implementation DemoCardView 46 | 47 | @synthesize parentController = parentController_; 48 | @synthesize zoomedIn = zoomedIn_; 49 | @synthesize tapRecognizer = tapRecognizer_; 50 | @synthesize dismissControl = dismissControl_; 51 | @synthesize demoView = demoView_; 52 | @synthesize actualDemoView = actualDemoView_; 53 | 54 | - (id)initWithFrame:(CGRect)frame { 55 | self = [super initWithFrame:frame]; 56 | if (self) { 57 | CALayer *layer = self.layer; 58 | layer.cornerRadius = 5.0; 59 | layer.backgroundColor = [UIColor whiteColor].CGColor; 60 | layer.opaque = YES; 61 | layer.shadowOffset = CGSizeMake(4, 8); 62 | layer.shadowRadius = 3; 63 | 64 | dismissControl_ = [[DismissControl alloc] initWithFrame:CGRectMake(0, 0, 20, 20)]; 65 | [dismissControl_ setTarget:self action:@selector(dismissTapped)]; 66 | 67 | tapRecognizer_ = [[UITapGestureRecognizer alloc] initWithTarget:self 68 | action:@selector(viewTapped)]; 69 | [self addGestureRecognizer:tapRecognizer_]; 70 | zoomedIn_ = NO; 71 | 72 | } 73 | return self; 74 | } 75 | 76 | - (void)dealloc { 77 | [tapRecognizer_ release]; 78 | [dismissControl_ release]; 79 | [demoView_ release]; 80 | [actualDemoView_ release]; 81 | } 82 | 83 | 84 | - (void)layoutSubviews { 85 | actualDemoView_.bounds = self.bounds; 86 | actualDemoView_.center = [GraphicsUtils centerOfRect:self.bounds]; 87 | } 88 | 89 | 90 | - (void)setDemoView:(id)demoView { 91 | [demoView_ autorelease]; 92 | demoView_ = [demoView retain]; 93 | [actualDemoView_ autorelease]; 94 | if ([demoView isKindOfClass:[UIView class]]) { 95 | actualDemoView_ = (UIView *)[demoView retain]; 96 | } else if ([demoView isKindOfClass:[UIViewController class]]) { 97 | actualDemoView_ = [((UIViewController *)demoView).view retain]; 98 | } 99 | [actualDemoView_ removeFromSuperview]; 100 | actualDemoView_.userInteractionEnabled = NO; 101 | [self addSubview:actualDemoView_]; 102 | [self setNeedsLayout]; 103 | } 104 | 105 | - (void)animationDidStop:(NSString *)animation 106 | finished:(BOOL)flag 107 | context:(void *)context { 108 | // Add the shadow. 109 | if ([animation isEqualToString:@"zoom in"]) { 110 | CALayer *layer = self.layer; 111 | [CATransaction setAnimationDuration:0]; 112 | layer.shadowOpacity = 0.5; 113 | 114 | // Add the close box to the view 115 | CGPoint origin = [self convertPoint:self.bounds.origin 116 | toView:self.parentController.view]; 117 | dismissControl_.center = origin; 118 | [self.parentController.view insertSubview:dismissControl_ 119 | belowSubview:self]; 120 | [actualDemoView_ setUserInteractionEnabled:YES]; 121 | if ([demoView_ respondsToSelector:@selector(startAnimating)]) { 122 | [demoView_ startAnimating]; 123 | } 124 | } 125 | } 126 | 127 | - (void)viewTapped { 128 | // Zoom in the view and remove the tap recognizer. 129 | [self removeGestureRecognizer:tapRecognizer_]; 130 | 131 | // Make sure we are the topmost view. 132 | NSInteger cardCount = [self.parentController.cardViews count]; 133 | [self.parentController.cardLayoutView insertSubview:self atIndex:cardCount - 1]; 134 | if ([demoView_ respondsToSelector:@selector(displayName)]) { 135 | self.parentController.navigationItem.title = demoView_.displayName; 136 | } 137 | CGRect layoutFrame = self.parentController.cardLayoutView.frame; 138 | 139 | [UIView beginAnimations:@"zoom in" context:NULL]; 140 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 141 | [UIView setAnimationDuration:0.4]; 142 | [UIView setAnimationDelegate:self]; 143 | [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; 144 | 145 | 146 | self.center = [GraphicsUtils centerOfRect:layoutFrame]; 147 | self.transform = CGAffineTransformIdentity; 148 | 149 | zoomedIn_ = YES; 150 | 151 | [UIView commitAnimations]; 152 | } 153 | 154 | - (void)dismissTapped { 155 | self.parentController.navigationItem.title = nil; 156 | if ([demoView_ respondsToSelector:@selector(stopAnimating)]) { 157 | [demoView_ stopAnimating]; 158 | } 159 | [actualDemoView_ setUserInteractionEnabled:NO]; 160 | [self addGestureRecognizer:tapRecognizer_]; 161 | [dismissControl_ removeFromSuperview]; 162 | CALayer *layer = self.layer; 163 | layer.shadowOpacity = 0; 164 | zoomedIn_ = NO; 165 | [self.parentController.cardLayoutView setNeedsLayout]; 166 | } 167 | 168 | @end 169 | -------------------------------------------------------------------------------- /CADemo/DismissControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // DismissControl.h 3 | // 4 | // Created by Paul Franceus on 7/20/11. 5 | // 6 | // MIT License 7 | // 8 | // Copyright (c) 2011 Paul Franceus 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | // 28 | 29 | #import 30 | 31 | 32 | // A generic dismiss control -- like the control in springboard that comes 33 | // up to delete applications. 34 | @interface DismissControl : UIView { 35 | @private 36 | UIColor *textBackground_; 37 | UIColor *textForeground_; 38 | NSString *text_; 39 | 40 | UIColor *bezelColor_; 41 | UIColor *targetColor_; 42 | UIColor *targetBackgroundColor_; 43 | 44 | id target_; 45 | SEL action_; 46 | } 47 | 48 | @property(nonatomic, readwrite, retain) UIColor *textBackground; 49 | @property(nonatomic, readwrite, retain) UIColor *textForeground; 50 | @property(nonatomic, readwrite, copy) NSString *text; 51 | 52 | @property(nonatomic, readwrite, retain) UIColor *bezelColor; 53 | @property(nonatomic, readwrite, retain) UIColor *targetColor; 54 | @property(nonatomic, readwrite, retain) UIColor *targetBackgroundColor; 55 | 56 | @property(nonatomic, readwrite, retain) id target; 57 | 58 | - (void)setTarget:(id)target action:(SEL)sel; 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /CADemo/DismissControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // DismissControl.m 3 | // 4 | // Created by Paul Franceus on 7/20/11. 5 | // 6 | // MIT License 7 | // 8 | // Copyright (c) 2011 Paul Franceus 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | // 28 | 29 | #import "DismissControl.h" 30 | 31 | #import 32 | 33 | static const CGFloat kBezelHeight = 20.0; 34 | static const CGFloat kBezelWidth = 20.0; // square control 35 | static const CGSize kShadowOffset = {2.0, 2.0}; 36 | static const CGFloat kShadowOpacity = 0.5; 37 | static const CGFloat kShadowRadius = 2.0; 38 | static const CGFloat kTargetInset = 2.0; 39 | static const CGFloat kTargetLineWidth = 2.0; 40 | 41 | @implementation DismissControl 42 | 43 | @synthesize textBackground = textBackground_; 44 | @synthesize textForeground = textForeground_; 45 | @synthesize text = text_; 46 | 47 | @synthesize bezelColor = bezelColor_; 48 | @synthesize targetColor = targetColor_; 49 | @synthesize targetBackgroundColor = targetBackgroundColor_; 50 | 51 | @synthesize target = target_; 52 | 53 | - (void)setUp { 54 | // Set up the shadow. 55 | CALayer *layer = [self layer]; 56 | [layer setBackgroundColor:[[UIColor clearColor] CGColor]]; 57 | [layer setShadowOpacity:kShadowOpacity]; 58 | [layer setShadowOffset:kShadowOffset]; 59 | 60 | // Set up the colors. 61 | [self setTextBackground:[UIColor whiteColor]]; 62 | [self setTextForeground:[UIColor blackColor]]; 63 | [self setBackgroundColor:[UIColor clearColor]]; 64 | [self setBezelColor:[UIColor whiteColor]]; 65 | [self setTargetColor:[UIColor whiteColor]]; 66 | [self setTargetBackgroundColor:[UIColor blackColor]]; 67 | 68 | // Set up the gesture recognizer. 69 | SEL sel = @selector(controlDidTap:); 70 | UITapGestureRecognizer *tapGesture = 71 | [[[UITapGestureRecognizer alloc] initWithTarget:self 72 | action:sel] autorelease]; 73 | [tapGesture setNumberOfTapsRequired:1]; 74 | [tapGesture setNumberOfTouchesRequired:1]; 75 | [self addGestureRecognizer:tapGesture]; 76 | } 77 | 78 | - (id)initWithFrame:(CGRect)frame { 79 | self = [super initWithFrame:frame]; 80 | if (self) { 81 | [self setUp]; 82 | } 83 | return self; 84 | } 85 | 86 | - (id)initWithCoder:(NSCoder *)decoder { 87 | self = [super initWithCoder:decoder]; 88 | if (self) { 89 | [self setUp]; 90 | } 91 | return self; 92 | } 93 | 94 | - (void)dealloc { 95 | [self setTextBackground:nil]; 96 | [self setTextForeground:nil]; 97 | [self setText:nil]; 98 | 99 | [self setBezelColor:nil]; 100 | [self setTargetColor:nil]; 101 | [self setTargetBackgroundColor:nil]; 102 | 103 | [self setTarget:nil]; 104 | [super dealloc]; 105 | } 106 | 107 | - (CGRect)bezelRect { 108 | // NB: The bezel rect is square. 109 | return CGRectMake(0, 0, kBezelWidth, kBezelHeight); 110 | } 111 | 112 | - (void)drawRect:(CGRect)rect { 113 | UIBezierPath *shadowPath = [UIBezierPath bezierPath]; 114 | 115 | // Draw the label. 116 | if (text_) { 117 | UIFont *font = [UIFont boldSystemFontOfSize:11]; 118 | CGSize size = [text_ sizeWithFont:font]; 119 | CGRect tRect = CGRectMake(0, 0, 120 | size.width + kBezelWidth * 1.5, kBezelHeight); 121 | UIBezierPath *tPath = 122 | [UIBezierPath bezierPathWithRoundedRect:tRect 123 | byRoundingCorners:UIRectCornerAllCorners 124 | cornerRadii:CGSizeMake(kBezelWidth / 2, 125 | kBezelHeight / 2)]; 126 | [[self textBackground] setFill]; 127 | [tPath fill]; 128 | [shadowPath appendPath:tPath]; 129 | tRect.origin.y += (tRect.size.height - size.height) / 2; 130 | tRect.origin.x += kBezelWidth; 131 | [textForeground_ setFill]; 132 | [text_ drawInRect:tRect withFont:font]; 133 | } 134 | 135 | // Draw the bezel. 136 | CGRect bRect = [self bezelRect]; 137 | [[self bezelColor] setFill]; 138 | UIBezierPath *bezelPath = [UIBezierPath bezierPathWithOvalInRect:bRect]; 139 | [bezelPath fill]; 140 | [shadowPath appendPath:bezelPath]; 141 | [[self layer] setShadowPath:[shadowPath CGPath]]; 142 | 143 | // Draw the target background. 144 | bRect = CGRectInset(bRect, kTargetInset, kTargetInset); 145 | [[self targetBackgroundColor] setFill]; 146 | UIBezierPath *backgroundPath = [UIBezierPath bezierPathWithOvalInRect:bRect]; 147 | [backgroundPath fill]; 148 | 149 | // Draw the X. 150 | bRect = CGRectInset(bRect, kTargetInset * 2, kTargetInset * 2); 151 | UIBezierPath *xPath = [UIBezierPath bezierPath]; 152 | [xPath moveToPoint:CGPointMake(CGRectGetMinX(bRect), CGRectGetMinY(bRect))]; 153 | [xPath addLineToPoint:CGPointMake(CGRectGetMaxX(bRect), 154 | CGRectGetMaxY(bRect))]; 155 | [xPath moveToPoint:CGPointMake(CGRectGetMaxX(bRect), CGRectGetMinY(bRect))]; 156 | [xPath addLineToPoint:CGPointMake(CGRectGetMinX(bRect), 157 | CGRectGetMaxY(bRect))]; 158 | [[self targetColor] setStroke]; 159 | [xPath setLineWidth:kTargetLineWidth]; 160 | [xPath stroke]; 161 | 162 | } 163 | 164 | #pragma mark - Control 165 | 166 | - (void)setTarget:(id)target action:(SEL)sel { 167 | if (target_ != target) { 168 | [target_ release]; 169 | target_ = [target retain]; 170 | } 171 | action_ = sel; 172 | } 173 | 174 | - (void)controlDidTap:(UITapGestureRecognizer*)tapGesture { 175 | CGPoint pt = [tapGesture locationInView:self]; 176 | if (!CGRectContainsPoint([self bezelRect], pt)) { 177 | return; 178 | } 179 | if (target_) { 180 | if ([target_ respondsToSelector:action_]) { 181 | [target_ performSelector:action_ withObject:self]; 182 | } 183 | } 184 | } 185 | 186 | @end 187 | -------------------------------------------------------------------------------- /CADemo/GraphicsUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // GraphicsUtils.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/23/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | @interface GraphicsUtils : NSObject 33 | 34 | + (CGFloat)clamp:(CGFloat)value from:(CGFloat)minimum to:(CGFloat)maximum; 35 | 36 | + (CGFloat)scaleForSize:(CGSize)size inRect:(CGRect)rect; 37 | 38 | + (CGRect)centerSize:(CGSize)size inRect:(CGRect)rect; 39 | 40 | + (CGPoint)centerOfRect:(CGRect)rect; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /CADemo/GraphicsUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // GraphicsUtils.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/23/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import "GraphicsUtils.h" 31 | 32 | @implementation GraphicsUtils 33 | 34 | + (CGFloat)clamp:(CGFloat)value from:(CGFloat)minimum to:(CGFloat)maximum { 35 | if (value < minimum) { 36 | value = minimum; 37 | } else if (value > maximum) { 38 | value = maximum; 39 | } 40 | return value; 41 | } 42 | 43 | + (CGFloat)scaleForSize:(CGSize)size inRect:(CGRect)rect { 44 | CGFloat hScale = rect.size.width / size.width; 45 | CGFloat vScale = rect.size.height / size.height; 46 | 47 | return MIN(hScale, vScale); 48 | } 49 | 50 | + (CGRect)centerSize:(CGSize)size inRect:(CGRect)rect { 51 | CGFloat scale = [GraphicsUtils scaleForSize:size inRect:rect]; 52 | CGRect result; 53 | result.size = CGSizeMake(size.width * scale, size.height * scale); 54 | result.origin = CGPointMake(rect.origin.x + 0.5 * (rect.size.width - size.width), 55 | rect.origin.y + 0.5 * (rect.size.height - size.height)); 56 | return result; 57 | } 58 | 59 | + (CGPoint)centerOfRect:(CGRect)rect { 60 | CGFloat midx = CGRectGetMidX(rect); 61 | CGFloat midy = CGRectGetMidY(rect); 62 | return CGPointMake(midx, midy); 63 | } 64 | @end 65 | -------------------------------------------------------------------------------- /CADemo/GroupAnimationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GroupAnimationViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/25/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | 31 | #import 32 | 33 | #import "DemoCardView.h" 34 | 35 | @interface GroupAnimationViewController : UIViewController { 36 | NSTimer *dropTimer_; 37 | NSArray *images_; 38 | NSInteger counter_; 39 | } 40 | @end 41 | -------------------------------------------------------------------------------- /CADemo/GroupAnimationViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GroupAnimationViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/25/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | 31 | #import "GroupAnimationViewController.h" 32 | 33 | #import 34 | 35 | @implementation GroupAnimationViewController 36 | 37 | - (id)initWithFrame:(CGRect)frame { 38 | self = [super initWithNibName:nil bundle:nil]; 39 | if (self) { 40 | self.view.frame = frame; 41 | self.view.clipsToBounds = YES; 42 | images_ = [[NSArray arrayWithObjects: 43 | @"Browser.png", @"Calculator.png", @"Calendar.png", @"Chat.png", 44 | @"Clock.png", @"Graph.png", @"iPod.png", @"Maps.png", @"Notes.png", 45 | @"Phone.png", @"Settings.png", @"Weather.png", @"Wheel.png", nil] retain]; 46 | sranddev(); 47 | } 48 | return self; 49 | } 50 | 51 | - (void)dealloc { 52 | [self stopAnimating]; 53 | } 54 | 55 | #pragma mark - Animate a layer. 56 | 57 | - (void)dropLayer { 58 | if (++counter_ > 100) { 59 | counter_ = 100; 60 | [[self.view.layer.sublayers objectAtIndex:0] removeFromSuperlayer]; 61 | } 62 | CGRect bounds = self.view.bounds; 63 | CALayer *layer = [CALayer layer]; 64 | 65 | CGFloat size = 64 + (rand() % 2) * 32; 66 | layer.bounds = CGRectMake(0, 0, size, size); 67 | layer.position = CGPointMake(rand() % (int)bounds.size.width, rand() % (int)bounds.size.height); 68 | NSString *imageName = [images_ objectAtIndex:rand() % [images_ count]]; 69 | layer.contents = (id)[UIImage imageNamed:imageName].CGImage; 70 | [self.view.layer addSublayer:layer]; 71 | self.view.layer.sublayerTransform = CATransform3DMakePerspective(1000); 72 | 73 | CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"]; 74 | fade.fromValue = [NSNumber numberWithFloat:0]; 75 | fade.toValue = [NSNumber numberWithFloat:1.0]; 76 | fade.duration = 2.0; 77 | 78 | CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 79 | scale.fromValue = [NSNumber numberWithFloat:4.0]; 80 | scale.toValue = [NSNumber numberWithFloat:1.0]; 81 | scale.duration = 2.0; 82 | 83 | CABasicAnimation *flip = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"]; 84 | flip.fromValue = [NSNumber numberWithFloat:3 * M_PI]; 85 | flip.toValue = [NSNumber numberWithFloat:0]; 86 | flip.duration = 2.0; 87 | 88 | CABasicAnimation *z = [CABasicAnimation animationWithKeyPath:@"zPosition"]; 89 | z.fromValue = [NSNumber numberWithFloat:200]; 90 | z.toValue = [NSNumber numberWithFloat:0]; 91 | z.duration = 2.0; 92 | 93 | CAAnimationGroup *group = [CAAnimationGroup animation]; 94 | group.animations = [NSArray arrayWithObjects:fade, scale, flip, z, nil]; 95 | group.duration = 2.0; 96 | group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 97 | 98 | [layer addAnimation:group forKey:@"drop and fade in"]; 99 | } 100 | #pragma mark - 101 | #pragma mark DemoCardSubview methods 102 | 103 | - (NSString *)displayName { 104 | return @"Group Animations"; 105 | } 106 | 107 | - (void)startAnimating { 108 | [self dropLayer]; 109 | 110 | dropTimer_ = [[NSTimer scheduledTimerWithTimeInterval:0.3 111 | target:self 112 | selector:@selector(dropLayer) 113 | userInfo:nil 114 | repeats:YES] retain]; 115 | } 116 | 117 | - (void)stopAnimating { 118 | [dropTimer_ invalidate]; 119 | [dropTimer_ release]; 120 | } 121 | 122 | 123 | @end 124 | -------------------------------------------------------------------------------- /CADemo/GroupAnimationViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 11A511 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 534 12 | 13 | 14 | YES 15 | IBProxyObject 16 | IBUIView 17 | 18 | 19 | YES 20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 21 | 22 | 23 | YES 24 | 25 | YES 26 | 27 | 28 | 29 | 30 | YES 31 | 32 | IBFilesOwner 33 | IBIPadFramework 34 | 35 | 36 | IBFirstResponder 37 | IBIPadFramework 38 | 39 | 40 | 41 | 292 42 | {{0, 20}, {768, 1004}} 43 | 44 | 45 | 46 | 3 47 | MAA 48 | 49 | NO 50 | 51 | 2 52 | 53 | IBIPadFramework 54 | 55 | 56 | 57 | 58 | YES 59 | 60 | 61 | view 62 | 63 | 64 | 65 | 3 66 | 67 | 68 | 69 | 70 | YES 71 | 72 | 0 73 | 74 | 75 | 76 | 77 | 78 | -1 79 | 80 | 81 | File's Owner 82 | 83 | 84 | -2 85 | 86 | 87 | 88 | 89 | 2 90 | 91 | 92 | 93 | 94 | 95 | 96 | YES 97 | 98 | YES 99 | -1.CustomClassName 100 | -1.IBPluginDependency 101 | -2.CustomClassName 102 | -2.IBPluginDependency 103 | 2.IBPluginDependency 104 | 105 | 106 | YES 107 | GroupAnimationViewController 108 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 109 | UIResponder 110 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 111 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 112 | 113 | 114 | 115 | YES 116 | 117 | 118 | 119 | 120 | 121 | YES 122 | 123 | 124 | 125 | 126 | 3 127 | 128 | 129 | 130 | YES 131 | 132 | GroupAnimationViewController 133 | UIViewController 134 | 135 | IBProjectSource 136 | ./Classes/GroupAnimationViewController.h 137 | 138 | 139 | 140 | 141 | 0 142 | IBIPadFramework 143 | 144 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 145 | 146 | 147 | YES 148 | 3 149 | 534 150 | 151 | 152 | -------------------------------------------------------------------------------- /CADemo/ImplicitAnimationsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BasicAnimationsViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/25/11. Thanks for inspiration to BobMcCune http://bobmccune.com 6 | // MIT License 7 | // 8 | // Copyright (c) 2011 Paul Franceus 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | // 28 | 29 | /* 30 | * Simple demo showing implicit property animations. 31 | */ 32 | 33 | #import "DemoCardView.h" 34 | 35 | @interface ImplicitAnimationsViewController : UIViewController { 36 | CALayer *layer; 37 | UISwitch *actionsSwitch; 38 | } 39 | 40 | @property (nonatomic, retain) IBOutlet UISwitch *actionsSwitch; 41 | 42 | - (IBAction)toggleCornerRadius; 43 | - (IBAction)toggleBorder; 44 | - (IBAction)toggleOpacity; 45 | - (IBAction)toggleColor; 46 | - (IBAction)toggleBounds; 47 | - (IBAction)togglePosition; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /CADemo/ImplicitAnimationsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MIT License 3 | // 4 | // Copyright (c) 2011 Bob McCune http://bobmccune.com/ 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | #import "ImplicitAnimationsViewController.h" 25 | 26 | #import 27 | 28 | #import "GraphicsUtils.h" 29 | 30 | @interface ImplicitAnimationsViewController () 31 | 32 | @property(nonatomic,assign) CGPoint initialPosition; 33 | @property(nonatomic,assign) CGPoint movedPosition; 34 | @property(nonatomic,retain) UIColor *initialColor; 35 | @property(nonatomic,retain) UIColor *changedColor; 36 | @end 37 | 38 | @implementation ImplicitAnimationsViewController 39 | 40 | @synthesize initialPosition, movedPosition, initialColor, changedColor; 41 | 42 | - (NSString *)displayName { 43 | return @"Animatable Properties"; 44 | } 45 | 46 | - (void)startAnimating { 47 | 48 | } 49 | 50 | - (void)stopAnimating { 51 | 52 | } 53 | 54 | - (id)initWithFrame:(CGRect)frame { 55 | if ((self = [super initWithNibName:nil bundle:nil])) { 56 | self.view.frame = frame; 57 | layer = [CALayer layer]; 58 | layer.bounds = CGRectMake(0, 0, 300, 300); 59 | self.initialPosition = [GraphicsUtils centerOfRect:frame]; 60 | self.movedPosition = CGPointMake(self.initialPosition.x + 100, self.initialPosition.y + 150); 61 | layer.position = [GraphicsUtils centerOfRect:frame]; 62 | self.initialColor = [UIColor colorWithHue:0.1 saturation:.4 brightness:.9 alpha:1.0]; 63 | self.changedColor = [UIColor colorWithHue:0.8 saturation:.9 brightness:.6 alpha:1.0]; 64 | layer.backgroundColor = self.initialColor.CGColor; 65 | layer.borderColor = [UIColor blackColor].CGColor; 66 | layer.opacity = 1.0f; 67 | [self.view.layer addSublayer:layer]; 68 | } 69 | return self; 70 | } 71 | 72 | - (void)dealloc { 73 | [initialColor release]; 74 | [changedColor release]; 75 | [super dealloc]; 76 | } 77 | 78 | - (void)viewDidLoad { 79 | [super viewDidLoad]; 80 | self.actionsSwitch.on = NO; 81 | } 82 | 83 | - (IBAction)toggleColor { 84 | [CATransaction setDisableActions:actionsSwitch.on]; 85 | layer.backgroundColor = (layer.backgroundColor == self.initialColor.CGColor) ? 86 | self.changedColor.CGColor : self.initialColor.CGColor; 87 | } 88 | 89 | - (IBAction)toggleCornerRadius { 90 | [CATransaction setDisableActions:actionsSwitch.on]; 91 | layer.cornerRadius = (layer.cornerRadius == 0.0f) ? 60.0f : 0.0f; 92 | } 93 | 94 | - (IBAction)toggleBorder { 95 | [CATransaction setDisableActions:actionsSwitch.on]; 96 | layer.borderWidth = (layer.borderWidth == 0.0f) ? 10.0f : 0.0f; 97 | } 98 | 99 | - (IBAction)toggleOpacity { 100 | [CATransaction setDisableActions:actionsSwitch.on]; 101 | layer.opacity = (layer.opacity == 1.0f) ? 0.3f : 1.0f; 102 | } 103 | 104 | - (IBAction)toggleBounds { 105 | [CATransaction setDisableActions:actionsSwitch.on]; 106 | CGRect bounds = layer.bounds; 107 | bounds.size.width += layer.bounds.size.width == layer.bounds.size.height ? 150 : -150; 108 | layer.bounds = bounds; 109 | } 110 | 111 | - (IBAction)togglePosition { 112 | [CATransaction setDisableActions:actionsSwitch.on]; 113 | layer.position = 114 | layer.position.x == self.initialPosition.x ? self.movedPosition : self.initialPosition; 115 | } 116 | 117 | @synthesize actionsSwitch; 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /CADemo/KeyPathAnimationView.h: -------------------------------------------------------------------------------- 1 | // 2 | // KeyPathAnimationView.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/23/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | #import "DemoCardView.h" 33 | 34 | @interface KeyPathAnimationView : UIView 35 | 36 | - (void)runAnimation; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /CADemo/KeyPathAnimationView.m: -------------------------------------------------------------------------------- 1 | // 2 | // KeyPathAnimationView.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/23/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import "KeyPathAnimationView.h" 31 | @interface KeyPathAnimationView () 32 | 33 | @property(nonatomic, retain) NSMutableArray *touchPoints; 34 | @property(nonatomic, retain) UITapGestureRecognizer *tapRecognizer; 35 | @property(nonatomic, retain) CALayer *movingLayer; 36 | 37 | @end 38 | 39 | @implementation KeyPathAnimationView 40 | 41 | @synthesize touchPoints = touchPoints_; 42 | @synthesize tapRecognizer = tapRecognizer_; 43 | @synthesize movingLayer = movingLayer_; 44 | 45 | - (void)awakeFromNib { 46 | self.touchPoints = [NSMutableArray array]; 47 | tapRecognizer_ = [[UITapGestureRecognizer alloc] initWithTarget:self 48 | action:@selector(viewTapped)]; 49 | [self addGestureRecognizer:tapRecognizer_]; 50 | } 51 | 52 | - (void)dealloc { 53 | [touchPoints_ release]; 54 | [tapRecognizer_ release]; 55 | } 56 | 57 | - (void)drawRect:(CGRect)rect { 58 | // Drawing code 59 | for (NSValue *loc in touchPoints_) { 60 | CGPoint location = [loc CGPointValue]; 61 | [@"+" drawAtPoint:location withFont:[UIFont systemFontOfSize:24]]; 62 | } 63 | } 64 | 65 | #pragma mark - 66 | #pragma mark Event handling 67 | 68 | - (void)viewTapped { 69 | CGPoint location = [tapRecognizer_ locationInView:self]; 70 | [touchPoints_ addObject:[NSValue valueWithCGPoint:location]]; 71 | [self setNeedsDisplay]; 72 | } 73 | 74 | #pragma mark - 75 | #pragma mark KeyPathAnimationViewController methods 76 | 77 | - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { 78 | [touchPoints_ removeAllObjects]; 79 | [self setNeedsDisplay]; 80 | } 81 | 82 | - (void)runAnimation { 83 | NSInteger points = [touchPoints_ count]; 84 | if (points > 0) { 85 | CALayer *layer = self.layer; 86 | 87 | if (self.movingLayer) { 88 | [self.movingLayer removeFromSuperlayer]; 89 | } 90 | self.movingLayer = [CALayer layer]; 91 | NSString *path = [[NSBundle mainBundle] pathForResource:@"Wheel" ofType:@"png"]; 92 | CGImageRef imageRef = [UIImage imageWithContentsOfFile:path].CGImage; 93 | self.movingLayer.contents = (id)imageRef; 94 | self.movingLayer.bounds = CGRectMake(0, 0, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); 95 | self.movingLayer.position = [[touchPoints_ objectAtIndex:0] CGPointValue]; 96 | 97 | [layer addSublayer:self.movingLayer]; 98 | 99 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 100 | animation.removedOnCompletion = YES; 101 | animation.duration = 0.3 * points; 102 | animation.calculationMode = kCAAnimationCubicPaced; 103 | animation.rotationMode = kCAAnimationRotateAuto; 104 | animation.values = touchPoints_; 105 | animation.delegate = self; 106 | 107 | [self.movingLayer addAnimation:animation forKey:@"followPath"]; 108 | 109 | // Make sure the animation sticks after it's done. 110 | self.movingLayer.position = [[touchPoints_ lastObject] CGPointValue]; 111 | } 112 | } 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /CADemo/KeyPathAnimationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // KeyPathAnimationViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/23/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | #import "DemoCardView.h" 33 | 34 | @class KeyPathAnimationView; 35 | 36 | @interface KeyPathAnimationViewController : UIViewController 37 | 38 | 39 | @property (nonatomic, retain) IBOutlet UIBarButtonItem *goButton; 40 | @property (nonatomic, retain) IBOutlet KeyPathAnimationView *keyPathView; 41 | 42 | 43 | - (IBAction)runAnimation:(id)sender; 44 | 45 | @end 46 | 47 | -------------------------------------------------------------------------------- /CADemo/KeyPathAnimationViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // KeyPathAnimationViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/23/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import "KeyPathAnimationViewController.h" 31 | 32 | #import "KeyPathAnimationView.h" 33 | 34 | @implementation KeyPathAnimationViewController 35 | 36 | @synthesize goButton = goButton_; 37 | @synthesize keyPathView = keyPathView_; 38 | 39 | - (id)initWithFrame:(CGRect)frame { 40 | self = [super initWithNibName:nil bundle:nil]; 41 | if (self) { 42 | // Custom initialization 43 | self.view.frame = frame; 44 | } 45 | return self; 46 | } 47 | 48 | - (void)didReceiveMemoryWarning { 49 | // Releases the view if it doesn't have a superview. 50 | [super didReceiveMemoryWarning]; 51 | 52 | // Release any cached data, images, etc that aren't in use. 53 | } 54 | 55 | #pragma mark - View lifecycle 56 | 57 | - (void)viewDidLoad { 58 | [super viewDidLoad]; 59 | } 60 | 61 | - (void)viewDidUnload { 62 | [self setGoButton:nil]; 63 | [self setKeyPathView:nil]; 64 | [super viewDidUnload]; 65 | } 66 | 67 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 68 | // Return YES for supported orientations 69 | return YES; 70 | } 71 | 72 | - (void)dealloc { 73 | [goButton_ release]; 74 | [keyPathView_ release]; 75 | [super dealloc]; 76 | } 77 | 78 | - (IBAction)runAnimation:(id)sender { 79 | [keyPathView_ runAnimation]; 80 | } 81 | 82 | #pragma mark - 83 | #pragma mark DemoCardSubview methods 84 | 85 | - (NSString *)displayName { 86 | return @"Key Frame Animation"; 87 | } 88 | 89 | - (void)startAnimating { 90 | 91 | } 92 | 93 | - (void)stopAnimating { 94 | 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /CADemo/KeyPathAnimationViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 11A511 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 534 12 | 13 | 14 | YES 15 | IBUIBarButtonItem 16 | IBUIToolbar 17 | IBUIView 18 | IBProxyObject 19 | 20 | 21 | YES 22 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 23 | 24 | 25 | YES 26 | 27 | YES 28 | 29 | 30 | 31 | 32 | YES 33 | 34 | IBFilesOwner 35 | IBIPadFramework 36 | 37 | 38 | IBFirstResponder 39 | IBIPadFramework 40 | 41 | 42 | 43 | 292 44 | 45 | YES 46 | 47 | 48 | 282 49 | {{0, 44}, {768, 960}} 50 | 51 | 52 | 53 | _NS:195 54 | 55 | 3 56 | MQA 57 | 58 | 2 59 | 60 | 61 | IBIPadFramework 62 | 63 | 64 | 65 | 290 66 | {768, 44} 67 | 68 | 69 | 70 | _NS:345 71 | NO 72 | NO 73 | IBIPadFramework 74 | 75 | YES 76 | 77 | IBIPadFramework 78 | 79 | 5 80 | 81 | 82 | Run Animation 83 | IBIPadFramework 84 | 1 85 | 86 | 87 | 88 | 89 | 90 | {{0, 20}, {768, 1004}} 91 | 92 | 93 | 94 | 95 | 3 96 | MC42NjY2NjY2NjY3AA 97 | 98 | NO 99 | 100 | 2 101 | 102 | IBIPadFramework 103 | 104 | 105 | 106 | 107 | YES 108 | 109 | 110 | view 111 | 112 | 113 | 114 | 11 115 | 116 | 117 | 118 | keyPathView 119 | 120 | 121 | 122 | 14 123 | 124 | 125 | 126 | goButton 127 | 128 | 129 | 130 | 18 131 | 132 | 133 | 134 | runAnimation: 135 | 136 | 137 | 138 | 19 139 | 140 | 141 | 142 | 143 | YES 144 | 145 | 0 146 | 147 | 148 | 149 | 150 | 151 | -1 152 | 153 | 154 | File's Owner 155 | 156 | 157 | -2 158 | 159 | 160 | 161 | 162 | 2 163 | 164 | 165 | YES 166 | 167 | 168 | 169 | 170 | 171 | 172 | 13 173 | 174 | 175 | 176 | 177 | 15 178 | 179 | 180 | YES 181 | 182 | 183 | 184 | 185 | 186 | 187 | 16 188 | 189 | 190 | 191 | 192 | 17 193 | 194 | 195 | 196 | 197 | 198 | 199 | YES 200 | 201 | YES 202 | -1.CustomClassName 203 | -1.IBPluginDependency 204 | -2.CustomClassName 205 | -2.IBPluginDependency 206 | 13.CustomClassName 207 | 13.IBPluginDependency 208 | 15.IBPluginDependency 209 | 16.IBPluginDependency 210 | 17.IBPluginDependency 211 | 2.IBPluginDependency 212 | 213 | 214 | YES 215 | KeyPathAnimationViewController 216 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 217 | UIResponder 218 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 219 | KeyPathAnimationView 220 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 221 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 222 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 223 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 224 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 225 | 226 | 227 | 228 | YES 229 | 230 | 231 | 232 | 233 | 234 | YES 235 | 236 | 237 | 238 | 239 | 19 240 | 241 | 242 | 243 | YES 244 | 245 | KeyPathAnimationView 246 | UIView 247 | 248 | IBProjectSource 249 | ./Classes/KeyPathAnimationView.h 250 | 251 | 252 | 253 | KeyPathAnimationViewController 254 | UIViewController 255 | 256 | runAnimation: 257 | id 258 | 259 | 260 | runAnimation: 261 | 262 | runAnimation: 263 | id 264 | 265 | 266 | 267 | YES 268 | 269 | YES 270 | goButton 271 | keyPathView 272 | 273 | 274 | YES 275 | UIBarButtonItem 276 | KeyPathAnimationView 277 | 278 | 279 | 280 | YES 281 | 282 | YES 283 | goButton 284 | keyPathView 285 | 286 | 287 | YES 288 | 289 | goButton 290 | UIBarButtonItem 291 | 292 | 293 | keyPathView 294 | KeyPathAnimationView 295 | 296 | 297 | 298 | 299 | IBProjectSource 300 | ./Classes/KeyPathAnimationViewController.h 301 | 302 | 303 | 304 | 305 | 0 306 | IBIPadFramework 307 | 308 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 309 | 310 | 311 | YES 312 | 3 313 | 534 314 | 315 | 316 | -------------------------------------------------------------------------------- /CADemo/MagnifierView.h: -------------------------------------------------------------------------------- 1 | // 2 | // MagnifierView.h 3 | // Editions 4 | // 5 | // Created by Paul Franceus on 7/22/09. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | 31 | #import 32 | #import 33 | 34 | // This class presents a magnified view of an underlying view, at the point touched by a user. 35 | // It is supplied with an image by the superclass, which can either be a 36 | // directly supplied image or an image of the parent view. 37 | @interface MagnifierView : UIView { 38 | @private 39 | CALayer *layer_; // The layer representing the magnifier itself. 40 | CALayer *imageLayer_; // Layer that contains the image to be magnified. 41 | CGPoint touchPoint_; // Where we have touched. 42 | CGFloat magnificationFactor_; // How much we want to magnify the image. 43 | CGSize viewSize_; // Size of the view. 44 | CGSize imageViewSize_; // Size of the image view 45 | CGSize magnifierSize_; // Size of the magnifier. 46 | } 47 | 48 | @property(nonatomic,assign) CGPoint touchPoint; 49 | @property(nonatomic,assign) float magnificationFactor; 50 | 51 | - (void)setSourceImage:(UIImage *)image; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /CADemo/MagnifierView.m: -------------------------------------------------------------------------------- 1 | // 2 | // MagnifierView.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/22/09. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | 31 | #import "MagnifierView.h" 32 | #import "GraphicsUtils.h" 33 | 34 | @implementation MagnifierView 35 | 36 | @synthesize touchPoint=touchPoint_; 37 | @synthesize magnificationFactor=magnificationFactor_; 38 | 39 | static float const kDefaultMagnificationFactor = 2.0; 40 | static CGPoint const kImageOffset = {0.5, 0.8}; 41 | static CGPoint const kViewOffset = {0.0, 30.0}; 42 | static CGSize const kMagnifierFraction = {0.3, 0.3}; 43 | 44 | - (id)initWithFrame:(CGRect)frame { 45 | magnifierSize_ = CGSizeMake(frame.size.width * kMagnifierFraction.width, 46 | frame.size.width * kMagnifierFraction.height); 47 | CGRect portal = CGRectMake(0, 0, magnifierSize_.width, magnifierSize_.height); 48 | self = [super initWithFrame:portal]; 49 | if (self) { 50 | self.userInteractionEnabled = YES; 51 | viewSize_ = frame.size; 52 | magnificationFactor_ = kDefaultMagnificationFactor; 53 | layer_ = [[self layer] retain]; 54 | [layer_ setBounds:portal]; 55 | [layer_ setCornerRadius:10.0]; 56 | [layer_ setMasksToBounds:YES]; 57 | [layer_ setBorderColor:[[UIColor grayColor] CGColor]]; 58 | [layer_ setBorderWidth:4.0]; 59 | imageLayer_ = [[CALayer alloc] init]; 60 | [imageLayer_ setAnchorPoint:CGPointMake(0, 0)]; 61 | imageViewSize_ = CGSizeMake(viewSize_.width * magnificationFactor_, 62 | viewSize_.height * magnificationFactor_); 63 | [imageLayer_ setBounds:CGRectMake( 64 | 0, 0, imageViewSize_.width, imageViewSize_.height)]; 65 | [layer_ addSublayer:imageLayer_]; 66 | } 67 | return self; 68 | } 69 | 70 | #pragma mark Magnify methods. 71 | 72 | - (void)showMagnifierAtPoint:(CGPoint)touchPoint { 73 | layer_.hidden = NO; 74 | [self setTouchPoint:touchPoint]; 75 | [self setNeedsLayout]; 76 | } 77 | 78 | #pragma mark - 79 | #pragma mark touch handling 80 | 81 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 82 | UITouch *touch = [touches anyObject]; 83 | CGPoint originalTouch = [touch locationInView:self.superview]; 84 | [self showMagnifierAtPoint:originalTouch]; 85 | } 86 | 87 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 88 | UITouch *touch = [touches anyObject]; 89 | CGPoint originalTouch = [touch locationInView:self.superview]; 90 | [self showMagnifierAtPoint:originalTouch]; 91 | } 92 | 93 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 94 | } 95 | 96 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 97 | [self touchesEnded:touches withEvent:event]; 98 | } 99 | 100 | - (void)setSourceImage:(UIImage *)image { 101 | [imageLayer_ setContents:(id)[image CGImage]]; 102 | } 103 | 104 | - (void)layoutSubviews { 105 | // Position the layer on the screen. 106 | CGPoint position = CGPointMake( 107 | touchPoint_.x + kViewOffset.x, 108 | touchPoint_.y - magnifierSize_.height * 0.5 - kViewOffset.y); 109 | position.x = [GraphicsUtils clamp:position.x 110 | from:magnifierSize_.width * 0.5 111 | to:viewSize_.width - magnifierSize_.width * 0.5]; 112 | position.y = [GraphicsUtils clamp:position.y 113 | from:magnifierSize_.height * 0.5 114 | to:viewSize_.height - magnifierSize_.height * 0.5]; 115 | 116 | // Position the image within the magnifier. 117 | CGPoint imagePosition = CGPointMake( 118 | -touchPoint_.x * magnificationFactor_ + magnifierSize_.width * kImageOffset.x, 119 | -touchPoint_.y * magnificationFactor_ + magnifierSize_.height * kImageOffset.y); 120 | imagePosition.x = [GraphicsUtils clamp:imagePosition.x 121 | from:-imageViewSize_.width + magnifierSize_.width 122 | to:0]; 123 | imagePosition.y = [GraphicsUtils clamp:imagePosition.y 124 | from:-imageViewSize_.height + magnifierSize_.height 125 | to:0]; 126 | 127 | // Turn off implicit animations so that things happen immediately. 128 | [CATransaction setDisableActions:YES]; 129 | [layer_ setPosition:position]; 130 | [imageLayer_ setPosition:imagePosition]; 131 | } 132 | 133 | - (void)dealloc { 134 | [layer_ release]; 135 | [imageLayer_ release]; 136 | [super dealloc]; 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /CADemo/MagnifierViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MagnifierViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 11/23/09. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | #import "DemoCardView.h" 33 | 34 | @class MagnifierView; 35 | 36 | @interface MagnifierViewController : UIViewController { 37 | @private 38 | UIImageView *imageView_; 39 | MagnifierView *magnifierView_; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /CADemo/MagnifierViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MagnifierViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 11/23/09. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | 31 | #import "MagnifierViewController.h" 32 | #import "MagnifierView.h" 33 | 34 | @interface MagnifierViewController () 35 | 36 | @property(nonatomic, assign) CGRect frame; 37 | 38 | @end 39 | 40 | @implementation MagnifierViewController 41 | 42 | @synthesize frame = frame_; 43 | 44 | #pragma mark View controller methods. 45 | 46 | - (id)initWithFrame:(CGRect)frame { 47 | self = [super init]; 48 | if (self) { 49 | frame_ = frame; 50 | } 51 | return self; 52 | } 53 | 54 | - (void)loadView { 55 | imageView_ = [[UIImageView alloc] initWithFrame:frame_]; 56 | magnifierView_ = [[MagnifierView alloc] initWithFrame:frame_]; 57 | 58 | self.view = imageView_; 59 | [imageView_ addSubview:magnifierView_]; 60 | 61 | UIImage *image = [UIImage imageNamed:@"sydney.jpg"]; 62 | imageView_.image = image; 63 | imageView_.userInteractionEnabled = NO; 64 | [magnifierView_ setSourceImage:image]; 65 | } 66 | 67 | - (void)dealloc { 68 | [magnifierView_ removeFromSuperview]; 69 | [magnifierView_ release]; 70 | [super dealloc]; 71 | } 72 | 73 | #pragma mark - 74 | #pragma mark DemoCardSubview methods 75 | 76 | - (NSString *)displayName { 77 | return @"Magnifier using CALayers"; 78 | } 79 | 80 | - (void)startAnimating { 81 | 82 | } 83 | 84 | - (void)stopAnimating { 85 | 86 | } 87 | 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /CADemo/Media/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/.DS_Store -------------------------------------------------------------------------------- /CADemo/Media/Browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Browser.png -------------------------------------------------------------------------------- /CADemo/Media/Calculator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Calculator.png -------------------------------------------------------------------------------- /CADemo/Media/Calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Calendar.png -------------------------------------------------------------------------------- /CADemo/Media/Chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Chat.png -------------------------------------------------------------------------------- /CADemo/Media/Clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Clock.png -------------------------------------------------------------------------------- /CADemo/Media/Graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Graph.png -------------------------------------------------------------------------------- /CADemo/Media/Maps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Maps.png -------------------------------------------------------------------------------- /CADemo/Media/Notes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Notes.png -------------------------------------------------------------------------------- /CADemo/Media/Phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Phone.png -------------------------------------------------------------------------------- /CADemo/Media/Settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Settings.png -------------------------------------------------------------------------------- /CADemo/Media/Weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Weather.png -------------------------------------------------------------------------------- /CADemo/Media/Wheel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/Wheel.png -------------------------------------------------------------------------------- /CADemo/Media/glacier.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/glacier.jpg -------------------------------------------------------------------------------- /CADemo/Media/iPod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/iPod.png -------------------------------------------------------------------------------- /CADemo/Media/moab.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/moab.jpg -------------------------------------------------------------------------------- /CADemo/Media/paris.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/paris.JPG -------------------------------------------------------------------------------- /CADemo/Media/rainbow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/rainbow.jpg -------------------------------------------------------------------------------- /CADemo/Media/redrock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/redrock.jpg -------------------------------------------------------------------------------- /CADemo/Media/rickroll.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/rickroll.mp4 -------------------------------------------------------------------------------- /CADemo/Media/sydney.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CADemo/Media/sydney.jpg -------------------------------------------------------------------------------- /CADemo/MoviePlayerViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MoviePlayerViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/25/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | 31 | #import 32 | #import "DemoCardView.h" 33 | 34 | @class AVPlayer; 35 | @class AVPlayerLayer; 36 | 37 | @interface MoviePlayerViewController : UIViewController { 38 | AVPlayer *player_; 39 | AVPlayerLayer *playerLayer_; 40 | } 41 | @property(nonatomic, retain) AVPlayer *player; 42 | @property(nonatomic, retain) AVPlayerLayer *playerLayer; 43 | 44 | - (IBAction)sliderValueChanged:(UISlider *)sender; 45 | - (IBAction)spinIt:(id)sender; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /CADemo/MoviePlayerViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MoviePlayerViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/25/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import "MoviePlayerViewController.h" 31 | 32 | #import 33 | #import "GraphicsUtils.h" 34 | 35 | @implementation MoviePlayerViewController 36 | 37 | @synthesize player = player_; 38 | @synthesize playerLayer = playerLayer_; 39 | 40 | - (id)initWithFrame:(CGRect)frame { 41 | self = [super initWithNibName:nil bundle:nil]; 42 | if (self) { 43 | self.view.frame = frame; 44 | } 45 | return self; 46 | } 47 | 48 | - (void)dealloc { 49 | [self.player pause]; 50 | [player_ release]; 51 | [super dealloc]; 52 | } 53 | 54 | - (void)viewDidLoad { 55 | [super viewDidLoad]; 56 | self.view.backgroundColor = [UIColor darkGrayColor]; 57 | 58 | // Setup AVPlayer 59 | // You've been rickrolled. 60 | NSString *moviePath = [[NSBundle mainBundle] pathForResource:@"rickroll" ofType:@"mp4"]; 61 | self.player = [AVPlayer playerWithURL:[NSURL fileURLWithPath:moviePath]]; 62 | 63 | // Create and configure AVPlayerLayer 64 | self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 65 | self.playerLayer.bounds = CGRectMake(0, 0, 600, 300); 66 | self.playerLayer.position = CGPointMake(355, 400); 67 | self.playerLayer.borderColor = [UIColor darkGrayColor].CGColor; 68 | self.playerLayer.borderWidth = 10.0; 69 | self.playerLayer.shadowOffset = CGSizeMake(0, 3); 70 | self.playerLayer.shadowOpacity = 0.80; 71 | 72 | // Add perspective transform 73 | self.view.layer.sublayerTransform = CATransform3DMakePerspective(1000); 74 | [self.view.layer addSublayer:self.playerLayer]; 75 | } 76 | 77 | // Rotate the layer around the Y-axis as slider value is changed 78 | -(void)sliderValueChanged:(UISlider *)sender{ 79 | self.playerLayer.transform = CATransform3DMakeRotation([sender value], 0, 1, 0); 80 | } 81 | 82 | // Animate spinning video around X-axis 83 | - (void)spinIt:(id)sender { 84 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"]; 85 | animation.duration = 1.25f; 86 | animation.toValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(360)]; 87 | [self.playerLayer addAnimation:animation forKey:@"spinAnimation"]; 88 | } 89 | 90 | - (NSString *)displayName { 91 | return @"Movie in a layer"; 92 | } 93 | 94 | - (void)startAnimating { 95 | [self.player play]; 96 | } 97 | 98 | - (void)stopAnimating { 99 | [self.player pause]; 100 | } 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /CADemo/MoviePlayerViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 11A511 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 534 12 | 13 | 14 | YES 15 | IBUISlider 16 | IBUIBarButtonItem 17 | IBUIToolbar 18 | IBUIView 19 | IBProxyObject 20 | 21 | 22 | YES 23 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 24 | 25 | 26 | YES 27 | 28 | YES 29 | 30 | 31 | 32 | 33 | YES 34 | 35 | IBFilesOwner 36 | IBIPadFramework 37 | 38 | 39 | IBFirstResponder 40 | IBIPadFramework 41 | 42 | 43 | 44 | 274 45 | 46 | YES 47 | 48 | 49 | 290 50 | 51 | YES 52 | 53 | 54 | 292 55 | {{462, 11}, {294, 23}} 56 | 57 | 58 | 59 | _NS:605 60 | NO 61 | IBIPadFramework 62 | 0 63 | 0 64 | 0.5 65 | -1 66 | 67 | 68 | {768, 44} 69 | 70 | 71 | 72 | _NS:345 73 | NO 74 | NO 75 | IBIPadFramework 76 | 77 | YES 78 | 79 | IBIPadFramework 80 | 81 | 5 82 | 83 | 84 | Spin 85 | IBIPadFramework 86 | 1 87 | 88 | 89 | 90 | IBIPadFramework 91 | 92 | 93 | 94 | 95 | 96 | 97 | {{0, 20}, {768, 1004}} 98 | 99 | 100 | 101 | 102 | 3 103 | MQA 104 | 105 | 2 106 | 107 | 108 | 109 | 2 110 | 111 | IBIPadFramework 112 | 113 | 114 | 115 | 116 | YES 117 | 118 | 119 | spinIt: 120 | 121 | 122 | 123 | 9 124 | 125 | 126 | 127 | sliderValueChanged: 128 | 129 | 130 | 13 131 | 132 | 10 133 | 134 | 135 | 136 | view 137 | 138 | 139 | 140 | 11 141 | 142 | 143 | 144 | 145 | YES 146 | 147 | 0 148 | 149 | 150 | 151 | 152 | 153 | 1 154 | 155 | 156 | YES 157 | 158 | 159 | 160 | 161 | 162 | -1 163 | 164 | 165 | File's Owner 166 | 167 | 168 | -2 169 | 170 | 171 | 172 | 173 | 3 174 | 175 | 176 | YES 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 4 185 | 186 | 187 | 188 | 189 | 7 190 | 191 | 192 | YES 193 | 194 | 195 | 196 | 197 | 198 | 6 199 | 200 | 201 | 202 | 203 | 8 204 | 205 | 206 | 207 | 208 | 209 | 210 | YES 211 | 212 | YES 213 | -1.CustomClassName 214 | -1.IBPluginDependency 215 | -2.CustomClassName 216 | -2.IBPluginDependency 217 | 1.IBPluginDependency 218 | 3.IBPluginDependency 219 | 4.IBPluginDependency 220 | 6.IBPluginDependency 221 | 7.IBPluginDependency 222 | 8.IBPluginDependency 223 | 224 | 225 | YES 226 | MoviePlayerViewController 227 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 228 | UIResponder 229 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 230 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 231 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 232 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 233 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 234 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 235 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 236 | 237 | 238 | 239 | YES 240 | 241 | 242 | 243 | 244 | 245 | YES 246 | 247 | 248 | 249 | 250 | 11 251 | 252 | 253 | 254 | YES 255 | 256 | MoviePlayerViewController 257 | UIViewController 258 | 259 | YES 260 | 261 | YES 262 | sliderValueChanged: 263 | spinIt: 264 | 265 | 266 | YES 267 | UISlider 268 | id 269 | 270 | 271 | 272 | YES 273 | 274 | YES 275 | sliderValueChanged: 276 | spinIt: 277 | 278 | 279 | YES 280 | 281 | sliderValueChanged: 282 | UISlider 283 | 284 | 285 | spinIt: 286 | id 287 | 288 | 289 | 290 | 291 | IBProjectSource 292 | ./Classes/MoviePlayerViewController.h 293 | 294 | 295 | 296 | 297 | 0 298 | IBIPadFramework 299 | 300 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 301 | 302 | 303 | YES 304 | 3 305 | 534 306 | 307 | 308 | -------------------------------------------------------------------------------- /CADemo/SublayerTransformView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SublayerTransformView.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. Based on Core Animation Demo by 6 | // Bob McCune http://bobmccune.com/ 7 | // 8 | // MIT License 9 | // 10 | // Copyright (c) 2011 Paul Franceus 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in 20 | // all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | // THE SOFTWARE. 29 | 30 | 31 | #import 32 | #import 33 | 34 | #import "DemoCardView.h" 35 | 36 | @interface SublayerTransformView : UIView { 37 | @private 38 | CALayer *rootLayer_; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CADemo/SublayerTransformView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SublayerTransformView.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. Based on Core Animation Demo by 6 | // Bob McCune http://bobmccune.com/ 7 | // 8 | // MIT License 9 | // 10 | // Copyright (c) 2011 Paul Franceus 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in 20 | // all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | // THE SOFTWARE. 29 | 30 | #import 31 | 32 | #import "SublayerTransformView.h" 33 | 34 | #import "GraphicsUtils.h" 35 | 36 | @interface SublayerTransformView () 37 | 38 | - (void)setUp; 39 | 40 | @property(nonatomic, assign) CGFloat shortSide; 41 | 42 | @end 43 | 44 | @implementation SublayerTransformView 45 | 46 | @synthesize shortSide = shortSide_; 47 | 48 | - (id)initWithFrame:(CGRect)frame { 49 | self = [super initWithFrame:frame]; 50 | if (self) { 51 | [self setUp]; 52 | } 53 | return self; 54 | } 55 | 56 | - (NSString *)displayName { 57 | return @"3D Perspective and Transforms"; 58 | } 59 | 60 | - (void)addLayersWithColors:(NSArray *)colors { 61 | CGRect bounds = self.bounds; 62 | shortSide_ = MIN(bounds.size.width, bounds.size.height); 63 | CGSize dimensions = CGSizeMake(shortSide_ * .5, shortSide_ * .5); 64 | CGRect layerBounds = CGRectMake(0, 0, dimensions.width, dimensions.height); 65 | CGFloat zPosition = 0; 66 | for (UIColor *color in colors) { 67 | CALayer *layer = [CALayer layer]; 68 | layer.backgroundColor = color.CGColor; 69 | layer.bounds = layerBounds; 70 | layer.position = [GraphicsUtils centerOfRect:bounds]; 71 | layer.opacity = 0.65; 72 | layer.cornerRadius = 10; 73 | layer.borderColor = [UIColor whiteColor].CGColor; 74 | layer.borderWidth = 1.0; 75 | layer.shadowOffset = CGSizeMake(0, 2); 76 | layer.shadowOpacity = 0.35; 77 | layer.shadowColor = [UIColor darkGrayColor].CGColor; 78 | layer.shouldRasterize = YES; 79 | layer.zPosition = zPosition; 80 | zPosition += 90; 81 | [rootLayer_ addSublayer:layer]; 82 | } 83 | } 84 | 85 | - (void)setUp { 86 | rootLayer_ = [CALayer layer]; 87 | // Apply perspective transform 88 | rootLayer_.backgroundColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor; 89 | rootLayer_.sublayerTransform = CATransform3DMakePerspective(1500); 90 | rootLayer_.frame = self.bounds; 91 | [self.layer addSublayer:rootLayer_]; 92 | 93 | NSArray *colors = [NSArray arrayWithObjects: 94 | [UIColor redColor], [UIColor greenColor], [UIColor purpleColor], nil]; 95 | [self addLayersWithColors:colors]; 96 | } 97 | 98 | - (void)rotateLayers { 99 | // Create basic animation to rotate around the Y and Z axes 100 | CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; 101 | transformAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; 102 | transformAnimation.toValue = 103 | [NSValue valueWithCATransform3D:CATransform3DMakeRotation(DEGREES_TO_RADIANS(150), 0, 1, 1)]; 104 | transformAnimation.duration = 1.5; 105 | transformAnimation.autoreverses = YES; 106 | transformAnimation.repeatCount = HUGE_VALF; 107 | transformAnimation.timingFunction = 108 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 109 | 110 | // TODO pure laziness here too. 111 | int increment = shortSide_ / 4; 112 | int tx = -increment; 113 | // Loop through the sublayers and attach the animations 114 | for (CALayer *layer in [rootLayer_ sublayers]) { 115 | [layer addAnimation:transformAnimation forKey:nil]; 116 | 117 | // Create animation to translate along the X axis 118 | CABasicAnimation *translateAnimation = 119 | [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; 120 | translateAnimation.fromValue = [NSValue valueWithCATransform3D:layer.transform]; 121 | translateAnimation.toValue = [NSNumber numberWithFloat:tx]; 122 | translateAnimation.duration = 1.5; 123 | translateAnimation.autoreverses = YES; 124 | translateAnimation.timingFunction = 125 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 126 | translateAnimation.repeatCount = HUGE_VALF; 127 | [layer addAnimation:translateAnimation forKey:nil]; 128 | tx += increment; 129 | } 130 | } 131 | 132 | - (void)startAnimating { 133 | [self rotateLayers]; 134 | } 135 | 136 | - (void)stopAnimating { 137 | for (CALayer *layer in [rootLayer_ sublayers]) { 138 | [layer removeAllAnimations]; 139 | } 140 | } 141 | 142 | @end 143 | -------------------------------------------------------------------------------- /CADemo/TransitionDirectionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionDirectionViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/24/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | @class TransitionDirectionViewController; 33 | 34 | @protocol TransitionDirectionControllerDelegate 35 | - (void)transitionDirectionController:(TransitionDirectionViewController *)controller 36 | didSelectDirection:(NSString *)direction; 37 | @end 38 | 39 | @interface TransitionDirectionViewController : UITableViewController { 40 | __weak id delegate_; 41 | NSArray *directions_; 42 | NSUInteger selectedIndex_; 43 | } 44 | 45 | @property(nonatomic, assign) id delegate; 46 | @property(nonatomic, readonly) NSString *selectedDirection; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /CADemo/TransitionDirectionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionDirectionViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/24/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | 31 | #import "TransitionDirectionViewController.h" 32 | 33 | 34 | @implementation TransitionDirectionViewController 35 | 36 | @synthesize delegate = delegate_; 37 | @synthesize selectedDirection = selectedDirection_; 38 | 39 | - (id)init{ 40 | self = [super initWithStyle:UITableViewStylePlain]; 41 | if (self) { 42 | // http://iphonedevwiki.net/index.php/CATransition 43 | directions_ = [[NSArray alloc] initWithObjects: 44 | kCATransitionFromLeft, 45 | kCATransitionFromRight, 46 | kCATransitionFromBottom, 47 | kCATransitionFromTop, 48 | nil]; 49 | } 50 | return self; 51 | } 52 | 53 | #pragma mark Table view methods 54 | 55 | - (CGSize)contentSizeForViewInPopover { 56 | return CGSizeMake(320, 44 * [directions_ count]); 57 | } 58 | 59 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 60 | return 1; 61 | } 62 | 63 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 64 | return [directions_ count]; 65 | } 66 | - (UITableViewCell *)tableView:(UITableView *)tableView 67 | cellForRowAtIndexPath:(NSIndexPath *)indexPath { 68 | 69 | static NSString *CellIdentifier = @"Cell"; 70 | 71 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 72 | if (cell == nil) { 73 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 74 | } 75 | NSString *string = [directions_ objectAtIndex:indexPath.row]; 76 | cell.textLabel.text = string; 77 | if (indexPath.row == selectedIndex_) { 78 | cell.accessoryType = UITableViewCellAccessoryCheckmark; 79 | } else { 80 | cell.accessoryType = UITableViewCellAccessoryNone; 81 | } 82 | 83 | return cell; 84 | } 85 | 86 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 87 | selectedIndex_ = indexPath.row; 88 | [delegate_ transitionDirectionController:self didSelectDirection:self.selectedDirection]; 89 | [tableView reloadData]; 90 | [self.navigationController popViewControllerAnimated:YES]; 91 | } 92 | 93 | - (NSString *)selectedDirection { 94 | return [directions_ objectAtIndex:selectedIndex_]; 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /CADemo/TransitionTypeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionTypeViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/24/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | @class TransitionTypeViewController; 33 | 34 | @protocol TransitionTypeControllerDelegate 35 | - (void)transitionTypeController:(TransitionTypeViewController *)controller 36 | didSelectType:(NSString *)type; 37 | @end 38 | 39 | @interface TransitionTypeViewController : UITableViewController { 40 | __weak id delegate_; 41 | NSArray *types_; 42 | NSUInteger selectedIndex_; 43 | } 44 | 45 | @property(nonatomic, assign) id delegate; 46 | @property(nonatomic, readonly) NSString *selectedType; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /CADemo/TransitionTypeViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionTypeViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/24/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | 31 | #import "TransitionTypeViewController.h" 32 | 33 | 34 | @implementation TransitionTypeViewController 35 | 36 | @synthesize delegate = delegate_; 37 | @synthesize selectedType = selectedType_; 38 | 39 | - (id)init{ 40 | self = [super initWithStyle:UITableViewStylePlain]; 41 | if (self) { 42 | // http://iphonedevwiki.net/index.php/CATransition 43 | types_ = [[NSArray alloc] initWithObjects: 44 | kCATransitionFade, 45 | kCATransitionMoveIn, 46 | kCATransitionPush, 47 | kCATransitionReveal, 48 | @"cameraIris", 49 | @"cameraIrisHollowOpen", 50 | @"cameraIrisHollowClose", 51 | @"cube", 52 | @"alignedCube", 53 | @"flip", 54 | @"alignedFlip", 55 | @"oglFlip", 56 | @"rotate", 57 | @"pageCurl", 58 | @"pageUnCurl", 59 | @"rippleEffect", 60 | @"suckEffect", 61 | nil]; 62 | } 63 | return self; 64 | } 65 | 66 | #pragma mark Table view methods 67 | 68 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 69 | return 1; 70 | } 71 | 72 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 73 | return [types_ count]; 74 | } 75 | 76 | - (CGSize)contentSizeForViewInPopover { 77 | return CGSizeMake(320, 44 * [types_ count]); 78 | } 79 | 80 | - (UITableViewCell *)tableView:(UITableView *)tableView 81 | cellForRowAtIndexPath:(NSIndexPath *)indexPath { 82 | 83 | static NSString *CellIdentifier = @"Cell"; 84 | 85 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 86 | if (cell == nil) { 87 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 88 | } 89 | NSString *string = [types_ objectAtIndex:indexPath.row]; 90 | cell.textLabel.text = string; 91 | if (indexPath.row == selectedIndex_) { 92 | cell.accessoryType = UITableViewCellAccessoryCheckmark; 93 | } else { 94 | cell.accessoryType = UITableViewCellAccessoryNone; 95 | } 96 | 97 | return cell; 98 | } 99 | 100 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 101 | selectedIndex_ = indexPath.row; 102 | [delegate_ transitionTypeController:self didSelectType:self.selectedType]; 103 | [tableView reloadData]; 104 | [self.navigationController popViewControllerAnimated:YES]; 105 | } 106 | 107 | - (NSString *)selectedType { 108 | return [types_ objectAtIndex:selectedIndex_]; 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /CADemo/TransitionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionViewController.h 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/24/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import 31 | 32 | #import "DemoCardView.h" 33 | #import "TransitionTypeViewController.h" 34 | #import "TransitionDirectionViewController.h" 35 | 36 | @interface TransitionViewController : UIViewController 37 | { 38 | NSUInteger imageIndex_; 39 | NSArray *images_; 40 | CATransition *transition_; 41 | NSTimer *repeatTimer_; 42 | } 43 | 44 | @property(nonatomic, retain) IBOutlet UIToolbar *toolbar; 45 | @property(nonatomic, retain) IBOutlet UIBarButtonItem *transitionButton; 46 | @property(nonatomic, retain) IBOutlet UIBarButtonItem *directionButton; 47 | @property(nonatomic, retain) IBOutlet UIImageView *imageView; 48 | 49 | - (IBAction)showTransitionPopover:(id)sender; 50 | - (IBAction)showDirectionPopover:(id)sender; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /CADemo/TransitionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TransitionViewController.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/24/11. 6 | // 7 | // MIT License 8 | // 9 | // Copyright (c) 2011 Paul Franceus 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 | 30 | #import "TransitionViewController.h" 31 | 32 | #import 33 | #import "TransitionTypeViewController.h" 34 | #import "TransitionDirectionViewController.h" 35 | 36 | @interface TransitionViewController () 37 | 38 | @property(nonatomic, retain) TransitionTypeViewController *typeViewController; 39 | @property(nonatomic, retain) TransitionDirectionViewController *directionViewController; 40 | @property(nonatomic, retain) UIPopoverController *typePopover; 41 | @property(nonatomic, retain) UIPopoverController *directionPopover; 42 | 43 | @end 44 | 45 | 46 | @implementation TransitionViewController 47 | @synthesize toolbar = toolbar_; 48 | @synthesize transitionButton = transitionButton_; 49 | @synthesize directionButton = directionButton_; 50 | @synthesize imageView = imageView_; 51 | @synthesize typeViewController = typeViewController_; 52 | @synthesize directionViewController = directionViewController_; 53 | @synthesize typePopover = typePopover_; 54 | @synthesize directionPopover = directionPopover_; 55 | 56 | - (id)initWithFrame:(CGRect)frame { 57 | self = [super initWithNibName:nil bundle:nil]; 58 | if (self) { 59 | self.view.frame = frame; 60 | transition_ = [[CATransition animation] retain]; 61 | transition_.type = typeViewController_.selectedType; 62 | transition_.subtype = directionViewController_.selectedDirection; 63 | transition_.duration = .75; 64 | transition_.timingFunction = 65 | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 66 | transition_.removedOnCompletion = YES; 67 | } 68 | return self; 69 | } 70 | 71 | - (void)dealloc { 72 | [images_ release]; 73 | [transition_ release]; 74 | [imageView_ release]; 75 | [repeatTimer_ invalidate]; 76 | [repeatTimer_ release]; 77 | [toolbar_ release]; 78 | [transitionButton_ release]; 79 | [directionButton_ release]; 80 | [typePopover_ release]; 81 | [typeViewController_ release]; 82 | [directionPopover_ release]; 83 | [directionViewController_ release]; 84 | [super dealloc]; 85 | } 86 | 87 | - (void)animate { 88 | if (++imageIndex_ >= [images_ count]) { 89 | imageIndex_ = 0; 90 | } 91 | 92 | self.imageView.layer.contents = (id)[UIImage imageNamed:[images_ objectAtIndex:imageIndex_]].CGImage; 93 | [self.imageView.layer addAnimation:transition_ forKey:@"Transition"]; 94 | } 95 | 96 | #pragma mark - 97 | #pragma mark DemoCardSubview methods 98 | 99 | - (NSString *)displayName { 100 | return @"Core Animation Transitions"; 101 | } 102 | 103 | - (void)startAnimating { 104 | repeatTimer_ = [[NSTimer scheduledTimerWithTimeInterval:3 105 | target:self 106 | selector:@selector(animate) 107 | userInfo:nil 108 | repeats:YES] retain]; 109 | } 110 | 111 | - (void)stopAnimating { 112 | [repeatTimer_ invalidate]; 113 | [repeatTimer_ release]; 114 | repeatTimer_ = nil; 115 | } 116 | 117 | #pragma mark - View lifecycle 118 | 119 | - (void)viewDidLoad { 120 | [super viewDidLoad]; 121 | 122 | images_ = [[NSArray arrayWithObjects:@"glacier.jpg", @"moab.jpg", @"paris.JPG", @"rainbow.jpg", 123 | @"redrock.jpg", @"sydney.jpg", nil] retain]; 124 | self.typeViewController = [[[TransitionTypeViewController alloc] init] autorelease]; 125 | self.typeViewController.delegate = self; 126 | self.typePopover = [[[UIPopoverController alloc] 127 | initWithContentViewController:self.typeViewController] autorelease]; 128 | 129 | self.directionViewController = [[[TransitionDirectionViewController alloc] init] autorelease]; 130 | self.directionViewController.delegate = self; 131 | self.directionPopover = [[[UIPopoverController alloc] 132 | initWithContentViewController:self.directionViewController] autorelease]; 133 | self.imageView.layer.contents = (id)[UIImage imageNamed:[images_ objectAtIndex:0]].CGImage; 134 | self.imageView.backgroundColor = [UIColor blackColor]; 135 | self.view.layer.backgroundColor = [UIColor blackColor].CGColor; 136 | } 137 | 138 | - (void)viewDidUnload { 139 | [self setDirectionButton:nil]; 140 | [self setTransitionButton:nil]; 141 | [self setToolbar:nil]; 142 | [self setImageView:nil]; 143 | [super viewDidUnload]; 144 | // Release any retained subviews of the main view. 145 | // e.g. self.myOutlet = nil; 146 | } 147 | 148 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 149 | return NO; 150 | } 151 | 152 | - (IBAction)showTransitionPopover:(id)sender { 153 | [self.typePopover presentPopoverFromBarButtonItem:sender 154 | permittedArrowDirections:UIPopoverArrowDirectionAny 155 | animated:YES]; 156 | } 157 | 158 | - (IBAction)showDirectionPopover:(id)sender { 159 | [self.directionPopover presentPopoverFromBarButtonItem:sender 160 | permittedArrowDirections:UIPopoverArrowDirectionAny 161 | animated:YES]; 162 | } 163 | 164 | #pragma mark - 165 | #pragma mark Delegate methods. 166 | 167 | - (void)transitionTypeController:(TransitionTypeViewController *)controller 168 | didSelectType:(NSString *)type { 169 | [self.typePopover dismissPopoverAnimated:YES]; 170 | transition_.type = typeViewController_.selectedType; 171 | } 172 | 173 | - (void)transitionDirectionController:(TransitionDirectionViewController *)controller 174 | didSelectDirection:(NSString *)direction { 175 | [self.directionPopover dismissPopoverAnimated:YES]; 176 | transition_.subtype = directionViewController_.selectedDirection; 177 | } 178 | 179 | @end 180 | -------------------------------------------------------------------------------- /CADemo/TransitionViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1056 5 | 11A511 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 534 12 | 13 | 14 | YES 15 | IBUIBarButtonItem 16 | IBUIToolbar 17 | IBUIImageView 18 | IBUIView 19 | IBProxyObject 20 | 21 | 22 | YES 23 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 24 | 25 | 26 | YES 27 | 28 | YES 29 | 30 | 31 | 32 | 33 | YES 34 | 35 | IBFilesOwner 36 | IBIPadFramework 37 | 38 | 39 | IBFirstResponder 40 | IBIPadFramework 41 | 42 | 43 | 44 | 292 45 | 46 | YES 47 | 48 | 49 | 290 50 | {{0, -5}, {768, 44}} 51 | 52 | 53 | 54 | _NS:345 55 | NO 56 | NO 57 | IBIPadFramework 58 | 59 | YES 60 | 61 | IBIPadFramework 62 | 63 | 5 64 | 65 | 66 | Transition 67 | IBIPadFramework 68 | 1 69 | 70 | 71 | 72 | Direction 73 | IBIPadFramework 74 | 1 75 | 76 | 77 | 78 | 79 | 80 | 81 | 282 82 | {{0, 39}, {768, 965}} 83 | 84 | 85 | 86 | _NS:544 87 | NO 88 | IBIPadFramework 89 | 90 | 91 | {{0, 20}, {768, 1004}} 92 | 93 | 94 | 95 | 96 | 3 97 | MQA 98 | 99 | 2 100 | 101 | 102 | NO 103 | 104 | 2 105 | 106 | IBIPadFramework 107 | 108 | 109 | 110 | 111 | YES 112 | 113 | 114 | view 115 | 116 | 117 | 118 | 3 119 | 120 | 121 | 122 | transitionButton 123 | 124 | 125 | 126 | 12 127 | 128 | 129 | 130 | toolbar 131 | 132 | 133 | 134 | 13 135 | 136 | 137 | 138 | showTransitionPopover: 139 | 140 | 141 | 142 | 14 143 | 144 | 145 | 146 | showDirectionPopover: 147 | 148 | 149 | 150 | 15 151 | 152 | 153 | 154 | imageView 155 | 156 | 157 | 158 | 17 159 | 160 | 161 | 162 | directionButton 163 | 164 | 165 | 166 | 18 167 | 168 | 169 | 170 | 171 | YES 172 | 173 | 0 174 | 175 | 176 | 177 | 178 | 179 | -1 180 | 181 | 182 | File's Owner 183 | 184 | 185 | -2 186 | 187 | 188 | 189 | 190 | 2 191 | 192 | 193 | YES 194 | 195 | 196 | 197 | 198 | 199 | 200 | 6 201 | 202 | 203 | YES 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 7 212 | 213 | 214 | 215 | 216 | 8 217 | 218 | 219 | 220 | 221 | 9 222 | 223 | 224 | 225 | 226 | 16 227 | 228 | 229 | 230 | 231 | 232 | 233 | YES 234 | 235 | YES 236 | -1.CustomClassName 237 | -1.IBPluginDependency 238 | -2.CustomClassName 239 | -2.IBPluginDependency 240 | 16.IBPluginDependency 241 | 2.IBPluginDependency 242 | 6.IBPluginDependency 243 | 7.IBPluginDependency 244 | 8.IBPluginDependency 245 | 9.IBPluginDependency 246 | 247 | 248 | YES 249 | TransitionViewController 250 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 251 | UIResponder 252 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 253 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 254 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 255 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 256 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 257 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 258 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 259 | 260 | 261 | 262 | YES 263 | 264 | 265 | 266 | 267 | 268 | YES 269 | 270 | 271 | 272 | 273 | 18 274 | 275 | 276 | 277 | YES 278 | 279 | TransitionViewController 280 | UIViewController 281 | 282 | YES 283 | 284 | YES 285 | showDirectionPopover: 286 | showTransitionPopover: 287 | 288 | 289 | YES 290 | id 291 | id 292 | 293 | 294 | 295 | YES 296 | 297 | YES 298 | showDirectionPopover: 299 | showTransitionPopover: 300 | 301 | 302 | YES 303 | 304 | showDirectionPopover: 305 | id 306 | 307 | 308 | showTransitionPopover: 309 | id 310 | 311 | 312 | 313 | 314 | YES 315 | 316 | YES 317 | directionButton 318 | imageView 319 | toolbar 320 | transitionButton 321 | 322 | 323 | YES 324 | UIBarButtonItem 325 | UIImageView 326 | UIToolbar 327 | UIBarButtonItem 328 | 329 | 330 | 331 | YES 332 | 333 | YES 334 | directionButton 335 | imageView 336 | toolbar 337 | transitionButton 338 | 339 | 340 | YES 341 | 342 | directionButton 343 | UIBarButtonItem 344 | 345 | 346 | imageView 347 | UIImageView 348 | 349 | 350 | toolbar 351 | UIToolbar 352 | 353 | 354 | transitionButton 355 | UIBarButtonItem 356 | 357 | 358 | 359 | 360 | IBProjectSource 361 | ./Classes/TransitionViewController.h 362 | 363 | 364 | 365 | 366 | 0 367 | IBIPadFramework 368 | 369 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 370 | 371 | 372 | YES 373 | 3 374 | 534 375 | 376 | 377 | -------------------------------------------------------------------------------- /CADemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /CADemo/en.lproj/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1024 5 | 11A511 6 | 1617 7 | 1138 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 534 12 | 13 | 14 | YES 15 | IBProxyObject 16 | IBUINavigationController 17 | IBUIViewController 18 | IBUICustomObject 19 | IBUIWindow 20 | IBUINavigationBar 21 | IBUINavigationItem 22 | 23 | 24 | YES 25 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 26 | 27 | 28 | YES 29 | 30 | YES 31 | 32 | 33 | 34 | 35 | YES 36 | 37 | IBFilesOwner 38 | IBCocoaTouchFramework 39 | 40 | 41 | IBFirstResponder 42 | IBCocoaTouchFramework 43 | 44 | 45 | IBCocoaTouchFramework 46 | 47 | 48 | 49 | 1316 50 | 51 | {320, 480} 52 | 53 | 54 | 55 | 56 | 1 57 | MSAxIDEAA 58 | 59 | NO 60 | NO 61 | 62 | IBCocoaTouchFramework 63 | YES 64 | 65 | 66 | 67 | 68 | 1 69 | 1 70 | 71 | IBCocoaTouchFramework 72 | NO 73 | 74 | 75 | 256 76 | {0, 0} 77 | NO 78 | YES 79 | YES 80 | IBCocoaTouchFramework 81 | 82 | 83 | YES 84 | 85 | CardLayoutViewController 86 | 87 | 88 | IBCocoaTouchFramework 89 | 90 | 91 | CardLayoutViewController 92 | 93 | 94 | 1 95 | 1 96 | 97 | YES 98 | IBCocoaTouchFramework 99 | NO 100 | 101 | 102 | 103 | 104 | 105 | 106 | YES 107 | 108 | 109 | delegate 110 | 111 | 112 | 113 | 4 114 | 115 | 116 | 117 | window 118 | 119 | 120 | 121 | 5 122 | 123 | 124 | 125 | navigationController 126 | 127 | 128 | 129 | 15 130 | 131 | 132 | 133 | 134 | YES 135 | 136 | 0 137 | 138 | 139 | 140 | 141 | 142 | 2 143 | 144 | 145 | YES 146 | 147 | 148 | 149 | 150 | -1 151 | 152 | 153 | File's Owner 154 | 155 | 156 | 3 157 | 158 | 159 | 160 | 161 | -2 162 | 163 | 164 | 165 | 166 | 9 167 | 168 | 169 | YES 170 | 171 | 172 | 173 | 174 | 175 | 176 | 11 177 | 178 | 179 | 180 | 181 | 13 182 | 183 | 184 | YES 185 | 186 | 187 | 188 | CardLayoutViewController 189 | 190 | 191 | 14 192 | 193 | 194 | 195 | 196 | 197 | 198 | YES 199 | 200 | YES 201 | -1.CustomClassName 202 | -1.IBPluginDependency 203 | -2.CustomClassName 204 | -2.IBPluginDependency 205 | 11.IBPluginDependency 206 | 13.CustomClassName 207 | 13.IBPluginDependency 208 | 14.IBPluginDependency 209 | 2.IBAttributePlaceholdersKey 210 | 2.IBPluginDependency 211 | 3.CustomClassName 212 | 3.IBPluginDependency 213 | 9.IBPluginDependency 214 | 215 | 216 | YES 217 | UIApplication 218 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 219 | UIResponder 220 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 221 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 222 | CardLayoutViewController 223 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 224 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 225 | 226 | YES 227 | 228 | 229 | 230 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 231 | CADemoAppDelegate 232 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 233 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 234 | 235 | 236 | 237 | YES 238 | 239 | 240 | 241 | 242 | 243 | YES 244 | 245 | 246 | 247 | 248 | 16 249 | 250 | 251 | 252 | YES 253 | 254 | CADemoAppDelegate 255 | NSObject 256 | 257 | YES 258 | 259 | YES 260 | navigationController 261 | window 262 | 263 | 264 | YES 265 | UINavigationController 266 | UIWindow 267 | 268 | 269 | 270 | YES 271 | 272 | YES 273 | navigationController 274 | window 275 | 276 | 277 | YES 278 | 279 | navigationController 280 | UINavigationController 281 | 282 | 283 | window 284 | UIWindow 285 | 286 | 287 | 288 | 289 | IBProjectSource 290 | ./Classes/CADemoAppDelegate.h 291 | 292 | 293 | 294 | CardLayoutView 295 | UIView 296 | 297 | dataSource 298 | id 299 | 300 | 301 | dataSource 302 | 303 | dataSource 304 | id 305 | 306 | 307 | 308 | IBProjectSource 309 | ./Classes/CardLayoutView.h 310 | 311 | 312 | 313 | CardLayoutViewController 314 | UIViewController 315 | 316 | cardLayoutView 317 | CardLayoutView 318 | 319 | 320 | cardLayoutView 321 | 322 | cardLayoutView 323 | CardLayoutView 324 | 325 | 326 | 327 | IBProjectSource 328 | ./Classes/CardLayoutViewController.h 329 | 330 | 331 | 332 | 333 | 0 334 | IBCocoaTouchFramework 335 | 336 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 337 | 338 | 339 | 340 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 341 | 342 | 343 | YES 344 | 3 345 | 534 346 | 347 | 348 | -------------------------------------------------------------------------------- /CADemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CADemo 4 | // 5 | // Created by Paul Franceus on 7/20/11. 6 | // Copyright 2011 Google, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /CoreAnimationForBoulderIOS.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaulMaxime/CADemo/5607dcd991f19cac90fa15579b520409005c8cb4/CoreAnimationForBoulderIOS.pdf -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This project is the demo I gave to the Boulder iOS Developer's meetup on Core Animation. I've also included my presentation slides as a PDF. --------------------------------------------------------------------------------