├── Classes ├── ITRFlipper.h └── ITRFlipper.m ├── Demo.png ├── Example.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── kiruthika.s.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── ITRFlipView.xcscheme │ └── xcschememanagement.plist ├── Example ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ └── Image.imageset │ │ ├── Contents.json │ │ └── index.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Controller │ ├── FirstViewController.h │ ├── FirstViewController.m │ ├── SecondViewController.h │ ├── SecondViewController.m │ ├── ThirdViewController.h │ ├── ThirdViewController.m │ ├── ViewController.h │ └── ViewController.m ├── ITRFlipper.h ├── ITRFlipper.m ├── Info.plist └── main.m ├── ITRFlipper.podspec ├── Podfile └── README.md /Classes/ITRFlipper.h: -------------------------------------------------------------------------------- 1 | // 2 | // ITRFlipper.h 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ITRFlipper; 12 | 13 | //Data source to set flip board screen 14 | @protocol ITRFlipperDataSource 15 | 16 | - (NSInteger) numberOfPagesinFlipper:(ITRFlipper *)flipper; 17 | - (UIView *) viewForPage:(NSInteger)page inFlipper:(ITRFlipper *) flipper; 18 | 19 | @end 20 | 21 | //enum forflip direction 22 | typedef enum { 23 | ITRFlipDirectionTop, 24 | ITRFlipDirectionBottom, 25 | } ITRFlipDirection; 26 | 27 | 28 | @interface ITRFlipper : UIView 29 | 30 | @property (nonatomic,retain) NSObject *dataSource; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Classes/ITRFlipper.m: -------------------------------------------------------------------------------- 1 | // 2 | // ITRFlipper.m 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import "ITRFlipper.h" 10 | 11 | @interface ITRFlipper() 12 | { 13 | NSInteger currentPage; 14 | NSInteger numberOfPages; 15 | 16 | CALayer *backgroundLayer; 17 | CALayer *flipLayer; 18 | 19 | ITRFlipDirection flipDirection; 20 | float startFlipAngle; 21 | float endFlipAngle; 22 | float currentAngle; 23 | 24 | BOOL setNextViewOnCompletion; 25 | BOOL animating; 26 | 27 | UITapGestureRecognizer *_tapRecognizer; 28 | UIPanGestureRecognizer *_panRecognizer; 29 | 30 | UIView *_currentView; 31 | UIView *_nextView; 32 | } 33 | 34 | @end 35 | 36 | @implementation ITRFlipper 37 | 38 | #pragma init method 39 | 40 | - (id)initWithFrame:(CGRect)frame { 41 | 42 | if ((self = [super initWithFrame:frame])) { 43 | 44 | _tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)]; 45 | _panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panned:)]; 46 | 47 | [self addGestureRecognizer:_panRecognizer]; 48 | [self addGestureRecognizer:_tapRecognizer]; 49 | } 50 | return self; 51 | } 52 | 53 | - (void) initFlip { 54 | 55 | //create image from UIView 56 | UIImage *currentImage = [self imageByRenderingView:_currentView]; 57 | UIImage *newImage = [self imageByRenderingView:_nextView]; 58 | 59 | _currentView.alpha = 0; 60 | _nextView.alpha = 0; 61 | 62 | backgroundLayer = [CALayer layer]; 63 | backgroundLayer.frame = self.bounds; 64 | backgroundLayer.zPosition = -300000; 65 | 66 | //create top & bottom layer 67 | CGRect rect = self.bounds; 68 | rect.size.height /= 2; 69 | 70 | CALayer *topLayer = [CALayer layer]; 71 | topLayer.frame = rect; 72 | topLayer.masksToBounds = YES; 73 | topLayer.contentsGravity = kCAGravityBottom; 74 | 75 | [backgroundLayer addSublayer:topLayer]; 76 | 77 | rect.origin.y = rect.size.height; 78 | 79 | CALayer *bottomLayer = [CALayer layer]; 80 | bottomLayer.frame = rect; 81 | bottomLayer.masksToBounds = YES; 82 | bottomLayer.contentsGravity = kCAGravityTop; 83 | 84 | [backgroundLayer addSublayer:bottomLayer]; 85 | 86 | if (flipDirection == ITRFlipDirectionBottom) {// flip from top to bottom 87 | topLayer.contents = (id) [newImage CGImage]; 88 | bottomLayer.contents = (id) [currentImage CGImage]; 89 | } else {//flip from bottom to top 90 | topLayer.contents = (id) [currentImage CGImage]; 91 | bottomLayer.contents = (id) [newImage CGImage]; 92 | } 93 | 94 | [self.layer addSublayer:backgroundLayer]; 95 | 96 | rect.origin.y = 0; 97 | 98 | flipLayer = [CATransformLayer layer]; 99 | flipLayer.anchorPoint = CGPointMake(0.5, 1.0); 100 | flipLayer.frame = rect; 101 | 102 | [self.layer addSublayer:flipLayer]; 103 | 104 | CALayer *backLayer = [CALayer layer]; 105 | backLayer.frame = flipLayer.bounds; 106 | backLayer.doubleSided = NO; 107 | backLayer.masksToBounds = YES; 108 | 109 | [flipLayer addSublayer:backLayer]; 110 | 111 | CALayer *frontLayer = [CALayer layer]; 112 | frontLayer.frame = flipLayer.bounds; 113 | frontLayer.doubleSided = NO; 114 | frontLayer.masksToBounds = YES; 115 | frontLayer.transform = CATransform3DMakeRotation(M_PI, 1.0, 0.0, 0); 116 | 117 | [flipLayer addSublayer:frontLayer]; 118 | 119 | if (flipDirection == ITRFlipDirectionBottom) { 120 | backLayer.contents = (id) [currentImage CGImage]; 121 | backLayer.contentsGravity = kCAGravityBottom; 122 | 123 | frontLayer.contents = (id) [newImage CGImage]; 124 | frontLayer.contentsGravity = kCAGravityTop; 125 | 126 | CATransform3D transform = CATransform3DMakeRotation(0.0, 1.0, 0.0, 0.0); 127 | transform.m34 = -1.0f / 1500.0f; 128 | 129 | flipLayer.transform = transform; 130 | 131 | currentAngle = startFlipAngle = 0; 132 | endFlipAngle = M_PI; 133 | } else { 134 | backLayer.contentsGravity = kCAGravityBottom; 135 | backLayer.contents = (id) [newImage CGImage]; 136 | 137 | frontLayer.contents = (id) [currentImage CGImage]; 138 | frontLayer.contentsGravity = kCAGravityTop; 139 | 140 | CATransform3D transform = CATransform3DMakeRotation(M_PI / 1.0, 1.0, 0.0, 0.0); 141 | transform.m34 = 1.0f / 1500.0f; 142 | 143 | flipLayer.transform = transform; 144 | 145 | currentAngle = startFlipAngle = M_PI; 146 | endFlipAngle = 0; 147 | } 148 | } 149 | 150 | #pragma flip 151 | 152 | - (void) flipPage { 153 | [self setFlipProgress:1.0 setDelegate:YES animate:YES]; 154 | } 155 | 156 | - (void) setFlipProgress:(float) progress setDelegate:(BOOL) setDelegate animate:(BOOL) animate { 157 | if (animate) { 158 | animating = YES; 159 | } 160 | 161 | float angle = startFlipAngle + progress * (endFlipAngle - startFlipAngle); 162 | 163 | float duration = animate ? 0.5 * fabs((angle - currentAngle) / (endFlipAngle - startFlipAngle)) : 0; 164 | 165 | currentAngle = angle; 166 | 167 | CATransform3D finalTransform = CATransform3DIdentity; 168 | finalTransform.m34 = 1.0f / 2500.0f; 169 | finalTransform = CATransform3DRotate(finalTransform, angle, 1.0, 0.0, 0.0); 170 | 171 | [flipLayer removeAllAnimations]; 172 | 173 | [CATransaction begin]; 174 | [CATransaction setAnimationDuration:duration]; 175 | 176 | flipLayer.transform = finalTransform; 177 | 178 | [CATransaction commit]; 179 | 180 | if (setDelegate) { 181 | [self performSelector:@selector(cleanupFlip) withObject:Nil afterDelay:duration]; 182 | } 183 | } 184 | 185 | //clear flip & background layer 186 | - (void) cleanupFlip { 187 | 188 | [backgroundLayer removeFromSuperlayer]; 189 | [flipLayer removeFromSuperlayer]; 190 | 191 | backgroundLayer = Nil; 192 | flipLayer = Nil; 193 | 194 | animating = NO; 195 | 196 | if (setNextViewOnCompletion && _nextView) { 197 | [_currentView removeFromSuperview]; 198 | _currentView = _nextView; 199 | _nextView = Nil; 200 | } 201 | 202 | _currentView.alpha = 1; 203 | } 204 | 205 | #pragma selector 206 | 207 | - (void)animationDidStop:(NSString *) animationID finished:(NSNumber *) finished context:(void *) context { 208 | [self cleanupFlip]; 209 | } 210 | 211 | 212 | #pragma setter 213 | 214 | - (void) setCurrentPage:(NSInteger) page { 215 | 216 | if (![self canSetCurrentPage:page]) { 217 | return; 218 | } 219 | 220 | setNextViewOnCompletion = YES; 221 | animating = YES; 222 | 223 | _nextView.alpha = 0; 224 | 225 | [UIView beginAnimations:@"" context:Nil]; 226 | [UIView setAnimationDuration:0.5]; 227 | [UIView setAnimationDelegate:self]; 228 | [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; 229 | 230 | _nextView.alpha = 1; 231 | 232 | [UIView commitAnimations]; 233 | } 234 | 235 | - (void) setCurrentPage:(NSInteger) page animated:(BOOL) animated { 236 | if (![self canSetCurrentPage:page]) { 237 | return; 238 | } 239 | 240 | setNextViewOnCompletion = YES; 241 | animating = YES; 242 | 243 | if (animated) { 244 | [self initFlip]; 245 | [self performSelector:@selector(flipPage) withObject:Nil afterDelay:0.001]; 246 | } else { 247 | [self animationDidStop:Nil finished:[NSNumber numberWithBool:NO] context:Nil]; 248 | } 249 | 250 | } 251 | 252 | - (void) setDataSource:(NSObject *) dataSource { 253 | 254 | _dataSource = dataSource; 255 | numberOfPages = [_dataSource numberOfPagesinFlipper:self]; 256 | currentPage = 0; 257 | 258 | //pagecontrol current page 259 | self.currentPage = 1; 260 | } 261 | 262 | 263 | - (BOOL) canSetCurrentPage:(NSInteger) page { 264 | 265 | if (page == currentPage) { 266 | return NO; 267 | } 268 | 269 | flipDirection = page < currentPage ? ITRFlipDirectionBottom : ITRFlipDirectionTop; 270 | currentPage= page; 271 | 272 | _nextView = [self.dataSource viewForPage:page inFlipper:self]; 273 | [self addSubview:_nextView]; 274 | 275 | return YES; 276 | } 277 | 278 | #pragma Gesture recognizer handler 279 | 280 | - (void) tapped:(UITapGestureRecognizer *) recognizer { 281 | 282 | if (!animating) { 283 | if (recognizer.state == UIGestureRecognizerStateRecognized) { 284 | NSInteger newPage; 285 | 286 | if ([recognizer locationInView:self].y < (self.bounds.size.height - self.bounds.origin.y) / 2) { 287 | newPage = MAX(1, currentPage - 1); 288 | } else { 289 | newPage = MIN(currentPage + 1, numberOfPages); 290 | } 291 | 292 | [self setCurrentPage:newPage animated:YES]; 293 | } 294 | } 295 | } 296 | 297 | 298 | - (void) panned:(UIPanGestureRecognizer *) recognizer { 299 | 300 | if (!animating) { 301 | 302 | static BOOL hasFailed; 303 | static BOOL initialized; 304 | static NSInteger lastPage; 305 | 306 | float translation = [recognizer translationInView:self].y; 307 | 308 | float progress = translation / self.bounds.size.height; 309 | 310 | if (flipDirection == ITRFlipDirectionTop) { 311 | progress = MIN(progress, 0); 312 | } else { 313 | progress = MAX(progress, 0); 314 | } 315 | 316 | switch (recognizer.state) { 317 | 318 | case UIGestureRecognizerStateBegan: 319 | hasFailed = FALSE; 320 | initialized = FALSE; 321 | animating = NO; 322 | setNextViewOnCompletion = NO; 323 | break; 324 | 325 | case UIGestureRecognizerStateChanged: 326 | 327 | if (!hasFailed) { 328 | if (!initialized) { 329 | 330 | lastPage = currentPage; 331 | if (translation > 0) { 332 | if (currentPage > 1) { 333 | [self canSetCurrentPage:currentPage - 1]; 334 | } else { 335 | hasFailed = TRUE; 336 | return; 337 | } 338 | } else { 339 | if (currentPage < numberOfPages) { 340 | [self canSetCurrentPage:currentPage + 1]; 341 | } else { 342 | hasFailed = TRUE; 343 | return; 344 | } 345 | } 346 | hasFailed = NO; 347 | initialized = TRUE; 348 | setNextViewOnCompletion = NO; 349 | 350 | [self initFlip]; 351 | } 352 | [self setFlipProgress:fabs(progress) setDelegate:NO animate:NO]; 353 | } 354 | break; 355 | 356 | case UIGestureRecognizerStateFailed: 357 | [self setFlipProgress:0.0 setDelegate:YES animate:YES]; 358 | currentPage = lastPage; 359 | break; 360 | 361 | case UIGestureRecognizerStateRecognized: 362 | if (hasFailed) { 363 | [self setFlipProgress:0.0 setDelegate:YES animate:YES]; 364 | currentPage = lastPage; 365 | return; 366 | } 367 | 368 | if (fabs((translation + [recognizer velocityInView:self].y / 4) / self.bounds.size.height) > 0.5) { 369 | setNextViewOnCompletion = YES; 370 | [self setFlipProgress:1.0 setDelegate:YES animate:YES]; 371 | } else { 372 | [self setFlipProgress:0.0 setDelegate:YES animate:YES]; 373 | currentPage = lastPage; 374 | } 375 | break; 376 | 377 | default: 378 | break; 379 | } 380 | } 381 | } 382 | 383 | //return UIView as UIImage by rendering view 384 | - (UIImage *) imageByRenderingView:(UIView *)view { 385 | 386 | CGFloat viewAlpha = view.alpha; 387 | view.alpha = 1; 388 | 389 | UIGraphicsBeginImageContext(view.bounds.size); 390 | [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 391 | UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext(); 392 | UIGraphicsEndImageContext(); 393 | 394 | view.alpha = viewAlpha; 395 | return resultingImage; 396 | } 397 | 398 | @end 399 | -------------------------------------------------------------------------------- /Demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITechRoof/ITRFlipper/c6e1a0a6c06df2a6e417f838c2a3a0e53894ab8b/Demo.png -------------------------------------------------------------------------------- /Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 83543EE41BCFBD3000E802C1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83543EE21BCFBD3000E802C1 /* Main.storyboard */; }; 11 | 83543EE91BCFBD3000E802C1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 83543EE71BCFBD3000E802C1 /* LaunchScreen.storyboard */; }; 12 | 83E4426F1BD0A6AF0026E402 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E442671BD0A6AF0026E402 /* SecondViewController.m */; settings = {ASSET_TAGS = (); }; }; 13 | 83E442701BD0A6AF0026E402 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E442681BD0A6AF0026E402 /* ViewController.m */; settings = {ASSET_TAGS = (); }; }; 14 | 83E442711BD0A6AF0026E402 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E4426A1BD0A6AF0026E402 /* FirstViewController.m */; settings = {ASSET_TAGS = (); }; }; 15 | 83E442721BD0A6AF0026E402 /* ThirdViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E4426D1BD0A6AF0026E402 /* ThirdViewController.m */; settings = {ASSET_TAGS = (); }; }; 16 | 83E442741BD0A6DD0026E402 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83E442731BD0A6DD0026E402 /* Assets.xcassets */; settings = {ASSET_TAGS = (); }; }; 17 | 83E442761BD0A6F00026E402 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 83E442751BD0A6F00026E402 /* Info.plist */; settings = {ASSET_TAGS = (); }; }; 18 | 83E442791BD0A7060026E402 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E442781BD0A7060026E402 /* AppDelegate.m */; settings = {ASSET_TAGS = (); }; }; 19 | 83E4427C1BD0A7230026E402 /* ITRFlipper.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E4427B1BD0A7230026E402 /* ITRFlipper.m */; settings = {ASSET_TAGS = (); }; }; 20 | 83E4427E1BD0A8230026E402 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E4427D1BD0A8230026E402 /* main.m */; settings = {ASSET_TAGS = (); }; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | 83543ED61BCFBD3000E802C1 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 83543EE31BCFBD3000E802C1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | 83543EE81BCFBD3000E802C1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 27 | 83E442671BD0A6AF0026E402 /* SecondViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecondViewController.m; path = ../Example/Controller/SecondViewController.m; sourceTree = ""; }; 28 | 83E442681BD0A6AF0026E402 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ViewController.m; path = ../Example/Controller/ViewController.m; sourceTree = ""; }; 29 | 83E442691BD0A6AF0026E402 /* FirstViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FirstViewController.h; path = ../Example/Controller/FirstViewController.h; sourceTree = ""; }; 30 | 83E4426A1BD0A6AF0026E402 /* FirstViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FirstViewController.m; path = ../Example/Controller/FirstViewController.m; sourceTree = ""; }; 31 | 83E4426B1BD0A6AF0026E402 /* SecondViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecondViewController.h; path = ../Example/Controller/SecondViewController.h; sourceTree = ""; }; 32 | 83E4426C1BD0A6AF0026E402 /* ThirdViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThirdViewController.h; path = ../Example/Controller/ThirdViewController.h; sourceTree = ""; }; 33 | 83E4426D1BD0A6AF0026E402 /* ThirdViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ThirdViewController.m; path = ../Example/Controller/ThirdViewController.m; sourceTree = ""; }; 34 | 83E4426E1BD0A6AF0026E402 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ViewController.h; path = ../Example/Controller/ViewController.h; sourceTree = ""; }; 35 | 83E442731BD0A6DD0026E402 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../Example/Assets.xcassets; sourceTree = ""; }; 36 | 83E442751BD0A6F00026E402 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../Example/Info.plist; sourceTree = ""; }; 37 | 83E442771BD0A7060026E402 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ../Example/AppDelegate.h; sourceTree = ""; }; 38 | 83E442781BD0A7060026E402 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = ../Example/AppDelegate.m; sourceTree = ""; }; 39 | 83E4427A1BD0A7230026E402 /* ITRFlipper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ITRFlipper.h; path = ../Classes/ITRFlipper.h; sourceTree = ""; }; 40 | 83E4427B1BD0A7230026E402 /* ITRFlipper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ITRFlipper.m; path = ../Classes/ITRFlipper.m; sourceTree = ""; }; 41 | 83E4427D1BD0A8230026E402 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ../Example/main.m; sourceTree = ""; }; 42 | /* End PBXFileReference section */ 43 | 44 | /* Begin PBXFrameworksBuildPhase section */ 45 | 83543ED31BCFBD3000E802C1 /* Frameworks */ = { 46 | isa = PBXFrameworksBuildPhase; 47 | buildActionMask = 2147483647; 48 | files = ( 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 83543ECD1BCFBD3000E802C1 = { 56 | isa = PBXGroup; 57 | children = ( 58 | 83543ED81BCFBD3000E802C1 /* ITRFlipView */, 59 | 83543ED71BCFBD3000E802C1 /* Products */, 60 | ); 61 | sourceTree = ""; 62 | }; 63 | 83543ED71BCFBD3000E802C1 /* Products */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | 83543ED61BCFBD3000E802C1 /* Example.app */, 67 | ); 68 | name = Products; 69 | sourceTree = ""; 70 | }; 71 | 83543ED81BCFBD3000E802C1 /* ITRFlipView */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 83543F121BCFE0F500E802C1 /* Controller */, 75 | 83543F0E1BCFE0C200E802C1 /* Classes */, 76 | 83E442771BD0A7060026E402 /* AppDelegate.h */, 77 | 83E442781BD0A7060026E402 /* AppDelegate.m */, 78 | 83543EE21BCFBD3000E802C1 /* Main.storyboard */, 79 | 83E442751BD0A6F00026E402 /* Info.plist */, 80 | 83E442731BD0A6DD0026E402 /* Assets.xcassets */, 81 | 83543EE71BCFBD3000E802C1 /* LaunchScreen.storyboard */, 82 | 83543ED91BCFBD3000E802C1 /* Supporting Files */, 83 | ); 84 | path = ITRFlipView; 85 | sourceTree = ""; 86 | }; 87 | 83543ED91BCFBD3000E802C1 /* Supporting Files */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | 83E4427D1BD0A8230026E402 /* main.m */, 91 | ); 92 | name = "Supporting Files"; 93 | sourceTree = ""; 94 | }; 95 | 83543F0E1BCFE0C200E802C1 /* Classes */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 83E4427A1BD0A7230026E402 /* ITRFlipper.h */, 99 | 83E4427B1BD0A7230026E402 /* ITRFlipper.m */, 100 | ); 101 | name = Classes; 102 | sourceTree = ""; 103 | }; 104 | 83543F121BCFE0F500E802C1 /* Controller */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 83E442691BD0A6AF0026E402 /* FirstViewController.h */, 108 | 83E4426A1BD0A6AF0026E402 /* FirstViewController.m */, 109 | 83E4426B1BD0A6AF0026E402 /* SecondViewController.h */, 110 | 83E442671BD0A6AF0026E402 /* SecondViewController.m */, 111 | 83E4426C1BD0A6AF0026E402 /* ThirdViewController.h */, 112 | 83E4426D1BD0A6AF0026E402 /* ThirdViewController.m */, 113 | 83E4426E1BD0A6AF0026E402 /* ViewController.h */, 114 | 83E442681BD0A6AF0026E402 /* ViewController.m */, 115 | ); 116 | name = Controller; 117 | sourceTree = ""; 118 | }; 119 | /* End PBXGroup section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | 83543ED51BCFBD3000E802C1 /* Example */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = 83543EED1BCFBD3000E802C1 /* Build configuration list for PBXNativeTarget "Example" */; 125 | buildPhases = ( 126 | 83543ED21BCFBD3000E802C1 /* Sources */, 127 | 83543ED31BCFBD3000E802C1 /* Frameworks */, 128 | 83543ED41BCFBD3000E802C1 /* Resources */, 129 | ); 130 | buildRules = ( 131 | ); 132 | dependencies = ( 133 | ); 134 | name = Example; 135 | productName = ITRFlipView; 136 | productReference = 83543ED61BCFBD3000E802C1 /* Example.app */; 137 | productType = "com.apple.product-type.application"; 138 | }; 139 | /* End PBXNativeTarget section */ 140 | 141 | /* Begin PBXProject section */ 142 | 83543ECE1BCFBD3000E802C1 /* Project object */ = { 143 | isa = PBXProject; 144 | attributes = { 145 | LastUpgradeCheck = 0700; 146 | ORGANIZATIONNAME = "kiruthika selvavinayagam"; 147 | TargetAttributes = { 148 | 83543ED51BCFBD3000E802C1 = { 149 | CreatedOnToolsVersion = 7.0; 150 | }; 151 | }; 152 | }; 153 | buildConfigurationList = 83543ED11BCFBD3000E802C1 /* Build configuration list for PBXProject "Example" */; 154 | compatibilityVersion = "Xcode 3.2"; 155 | developmentRegion = English; 156 | hasScannedForEncodings = 0; 157 | knownRegions = ( 158 | en, 159 | Base, 160 | ); 161 | mainGroup = 83543ECD1BCFBD3000E802C1; 162 | productRefGroup = 83543ED71BCFBD3000E802C1 /* Products */; 163 | projectDirPath = ""; 164 | projectRoot = ""; 165 | targets = ( 166 | 83543ED51BCFBD3000E802C1 /* Example */, 167 | ); 168 | }; 169 | /* End PBXProject section */ 170 | 171 | /* Begin PBXResourcesBuildPhase section */ 172 | 83543ED41BCFBD3000E802C1 /* Resources */ = { 173 | isa = PBXResourcesBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | 83E442761BD0A6F00026E402 /* Info.plist in Resources */, 177 | 83543EE91BCFBD3000E802C1 /* LaunchScreen.storyboard in Resources */, 178 | 83E442741BD0A6DD0026E402 /* Assets.xcassets in Resources */, 179 | 83543EE41BCFBD3000E802C1 /* Main.storyboard in Resources */, 180 | ); 181 | runOnlyForDeploymentPostprocessing = 0; 182 | }; 183 | /* End PBXResourcesBuildPhase section */ 184 | 185 | /* Begin PBXSourcesBuildPhase section */ 186 | 83543ED21BCFBD3000E802C1 /* Sources */ = { 187 | isa = PBXSourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | 83E4427C1BD0A7230026E402 /* ITRFlipper.m in Sources */, 191 | 83E4426F1BD0A6AF0026E402 /* SecondViewController.m in Sources */, 192 | 83E442721BD0A6AF0026E402 /* ThirdViewController.m in Sources */, 193 | 83E442711BD0A6AF0026E402 /* FirstViewController.m in Sources */, 194 | 83E442701BD0A6AF0026E402 /* ViewController.m in Sources */, 195 | 83E4427E1BD0A8230026E402 /* main.m in Sources */, 196 | 83E442791BD0A7060026E402 /* AppDelegate.m in Sources */, 197 | ); 198 | runOnlyForDeploymentPostprocessing = 0; 199 | }; 200 | /* End PBXSourcesBuildPhase section */ 201 | 202 | /* Begin PBXVariantGroup section */ 203 | 83543EE21BCFBD3000E802C1 /* Main.storyboard */ = { 204 | isa = PBXVariantGroup; 205 | children = ( 206 | 83543EE31BCFBD3000E802C1 /* Base */, 207 | ); 208 | name = Main.storyboard; 209 | path = ../Example; 210 | sourceTree = ""; 211 | }; 212 | 83543EE71BCFBD3000E802C1 /* LaunchScreen.storyboard */ = { 213 | isa = PBXVariantGroup; 214 | children = ( 215 | 83543EE81BCFBD3000E802C1 /* Base */, 216 | ); 217 | name = LaunchScreen.storyboard; 218 | path = ../Example; 219 | sourceTree = ""; 220 | }; 221 | /* End PBXVariantGroup section */ 222 | 223 | /* Begin XCBuildConfiguration section */ 224 | 83543EEB1BCFBD3000E802C1 /* Debug */ = { 225 | isa = XCBuildConfiguration; 226 | buildSettings = { 227 | ALWAYS_SEARCH_USER_PATHS = NO; 228 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 229 | CLANG_CXX_LIBRARY = "libc++"; 230 | CLANG_ENABLE_MODULES = YES; 231 | CLANG_ENABLE_OBJC_ARC = YES; 232 | CLANG_WARN_BOOL_CONVERSION = YES; 233 | CLANG_WARN_CONSTANT_CONVERSION = YES; 234 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 235 | CLANG_WARN_EMPTY_BODY = YES; 236 | CLANG_WARN_ENUM_CONVERSION = YES; 237 | CLANG_WARN_INT_CONVERSION = YES; 238 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 239 | CLANG_WARN_UNREACHABLE_CODE = YES; 240 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 241 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 242 | COPY_PHASE_STRIP = NO; 243 | DEBUG_INFORMATION_FORMAT = dwarf; 244 | ENABLE_STRICT_OBJC_MSGSEND = YES; 245 | ENABLE_TESTABILITY = YES; 246 | GCC_C_LANGUAGE_STANDARD = gnu99; 247 | GCC_DYNAMIC_NO_PIC = NO; 248 | GCC_NO_COMMON_BLOCKS = YES; 249 | GCC_OPTIMIZATION_LEVEL = 0; 250 | GCC_PREPROCESSOR_DEFINITIONS = ( 251 | "DEBUG=1", 252 | "$(inherited)", 253 | ); 254 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 255 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 256 | GCC_WARN_UNDECLARED_SELECTOR = YES; 257 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 258 | GCC_WARN_UNUSED_FUNCTION = YES; 259 | GCC_WARN_UNUSED_VARIABLE = YES; 260 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 261 | MTL_ENABLE_DEBUG_INFO = YES; 262 | ONLY_ACTIVE_ARCH = YES; 263 | SDKROOT = iphoneos; 264 | }; 265 | name = Debug; 266 | }; 267 | 83543EEC1BCFBD3000E802C1 /* Release */ = { 268 | isa = XCBuildConfiguration; 269 | buildSettings = { 270 | ALWAYS_SEARCH_USER_PATHS = NO; 271 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 272 | CLANG_CXX_LIBRARY = "libc++"; 273 | CLANG_ENABLE_MODULES = YES; 274 | CLANG_ENABLE_OBJC_ARC = YES; 275 | CLANG_WARN_BOOL_CONVERSION = YES; 276 | CLANG_WARN_CONSTANT_CONVERSION = YES; 277 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 278 | CLANG_WARN_EMPTY_BODY = YES; 279 | CLANG_WARN_ENUM_CONVERSION = YES; 280 | CLANG_WARN_INT_CONVERSION = YES; 281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 282 | CLANG_WARN_UNREACHABLE_CODE = YES; 283 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 284 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 285 | COPY_PHASE_STRIP = NO; 286 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 287 | ENABLE_NS_ASSERTIONS = NO; 288 | ENABLE_STRICT_OBJC_MSGSEND = YES; 289 | GCC_C_LANGUAGE_STANDARD = gnu99; 290 | GCC_NO_COMMON_BLOCKS = YES; 291 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 292 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 293 | GCC_WARN_UNDECLARED_SELECTOR = YES; 294 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 295 | GCC_WARN_UNUSED_FUNCTION = YES; 296 | GCC_WARN_UNUSED_VARIABLE = YES; 297 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 298 | MTL_ENABLE_DEBUG_INFO = NO; 299 | SDKROOT = iphoneos; 300 | VALIDATE_PRODUCT = YES; 301 | }; 302 | name = Release; 303 | }; 304 | 83543EEE1BCFBD3000E802C1 /* Debug */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 308 | INFOPLIST_FILE = Example/Info.plist; 309 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 310 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 311 | PRODUCT_BUNDLE_IDENTIFIER = ITR.ITRFlipView; 312 | PRODUCT_NAME = Example; 313 | }; 314 | name = Debug; 315 | }; 316 | 83543EEF1BCFBD3000E802C1 /* Release */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 320 | INFOPLIST_FILE = Example/Info.plist; 321 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 322 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 323 | PRODUCT_BUNDLE_IDENTIFIER = ITR.ITRFlipView; 324 | PRODUCT_NAME = Example; 325 | }; 326 | name = Release; 327 | }; 328 | /* End XCBuildConfiguration section */ 329 | 330 | /* Begin XCConfigurationList section */ 331 | 83543ED11BCFBD3000E802C1 /* Build configuration list for PBXProject "Example" */ = { 332 | isa = XCConfigurationList; 333 | buildConfigurations = ( 334 | 83543EEB1BCFBD3000E802C1 /* Debug */, 335 | 83543EEC1BCFBD3000E802C1 /* Release */, 336 | ); 337 | defaultConfigurationIsVisible = 0; 338 | defaultConfigurationName = Release; 339 | }; 340 | 83543EED1BCFBD3000E802C1 /* Build configuration list for PBXNativeTarget "Example" */ = { 341 | isa = XCConfigurationList; 342 | buildConfigurations = ( 343 | 83543EEE1BCFBD3000E802C1 /* Debug */, 344 | 83543EEF1BCFBD3000E802C1 /* Release */, 345 | ); 346 | defaultConfigurationIsVisible = 0; 347 | defaultConfigurationName = Release; 348 | }; 349 | /* End XCConfigurationList section */ 350 | }; 351 | rootObject = 83543ECE1BCFBD3000E802C1 /* Project object */; 352 | } 353 | -------------------------------------------------------------------------------- /Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example.xcodeproj/xcuserdata/kiruthika.s.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Example.xcodeproj/xcuserdata/kiruthika.s.xcuserdatad/xcschemes/ITRFlipView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Example.xcodeproj/xcuserdata/kiruthika.s.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ITRFlipView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 83543ED51BCFBD3000E802C1 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // 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. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/Image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "index.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Assets.xcassets/Image.imageset/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITechRoof/ITRFlipper/c6e1a0a6c06df2a6e417f838c2a3a0e53894ab8b/Example/Assets.xcassets/Image.imageset/index.png -------------------------------------------------------------------------------- /Example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit. 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /Example/Controller/FirstViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.h 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FirstViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Controller/FirstViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.m 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import "FirstViewController.h" 10 | 11 | @interface FirstViewController () 12 | 13 | @end 14 | 15 | @implementation FirstViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | /* 28 | #pragma mark - Navigation 29 | 30 | // In a storyboard-based application, you will often want to do a little preparation before navigation 31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 32 | // Get the new view controller using [segue destinationViewController]. 33 | // Pass the selected object to the new view controller. 34 | } 35 | */ 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/Controller/SecondViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.h 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SecondViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Controller/SecondViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.m 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import "SecondViewController.h" 10 | 11 | @interface SecondViewController () 12 | 13 | @end 14 | 15 | @implementation SecondViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | /* 28 | #pragma mark - Navigation 29 | 30 | // In a storyboard-based application, you will often want to do a little preparation before navigation 31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 32 | // Get the new view controller using [segue destinationViewController]. 33 | // Pass the selected object to the new view controller. 34 | } 35 | */ 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/Controller/ThirdViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.h 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ThirdViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Controller/ThirdViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.m 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import "ThirdViewController.h" 10 | 11 | @interface ThirdViewController () 12 | 13 | @end 14 | 15 | @implementation ThirdViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | /* 28 | #pragma mark - Navigation 29 | 30 | // In a storyboard-based application, you will often want to do a little preparation before navigation 31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 32 | // Get the new view controller using [segue destinationViewController]. 33 | // Pass the selected object to the new view controller. 34 | } 35 | */ 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/Controller/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface ViewController : UIViewController 13 | 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /Example/Controller/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "FirstViewController.h" 11 | #import "SecondViewController.h" 12 | #import "ThirdViewController.h" 13 | #import "ITRFlipper.h" 14 | 15 | 16 | @interface ViewController () 17 | { 18 | ITRFlipper *itrFlipper; 19 | FirstViewController *_firstViewController; 20 | SecondViewController *_secondViewController; 21 | ThirdViewController *_thirdViewController; 22 | } 23 | @end 24 | 25 | @implementation ViewController 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | 30 | UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 31 | _firstViewController = [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass(FirstViewController.class)]; 32 | _secondViewController = [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass(SecondViewController.class)]; 33 | _thirdViewController = [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass(ThirdViewController.class)]; 34 | 35 | //flipper view 36 | itrFlipper = [[ITRFlipper alloc] initWithFrame:self.view.bounds]; 37 | [itrFlipper setBackgroundColor:[UIColor clearColor]]; 38 | itrFlipper.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 39 | itrFlipper.dataSource = self; 40 | 41 | [self.view addSubview:itrFlipper]; 42 | } 43 | 44 | #pragma ITRFlipper datasource 45 | - (NSInteger) numberOfPagesinFlipper:(ITRFlipper *)pageFlipper { 46 | return 10; 47 | } 48 | 49 | - (UIView *) viewForPage:(NSInteger) page inFlipper:(ITRFlipper *) flipper { 50 | 51 | if(page % 3 == 0){ 52 | return _firstViewController.view; 53 | }else if(page % 3 == 1){ 54 | return _secondViewController.view; 55 | }else{ 56 | return _thirdViewController.view; 57 | } 58 | } 59 | 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Example/ITRFlipper.h: -------------------------------------------------------------------------------- 1 | // 2 | // ITRFlipper.h 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ITRFlipper; 12 | 13 | //Data source to set flip board screen 14 | @protocol ITRFlipperDataSource 15 | 16 | - (NSInteger) numberOfPagesinFlipper:(ITRFlipper *)flipper; 17 | - (UIView *) viewForPage:(NSInteger)page inFlipper:(ITRFlipper *) flipper; 18 | 19 | @end 20 | 21 | //enum forflip direction 22 | typedef enum { 23 | ITRFlipDirectionTop, 24 | ITRFlipDirectionBottom, 25 | } ITRFlipDirection; 26 | 27 | 28 | @interface ITRFlipper : UIView 29 | 30 | @property (nonatomic,retain) NSObject *dataSource; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Example/ITRFlipper.m: -------------------------------------------------------------------------------- 1 | // 2 | // ITRFlipper.m 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import "ITRFlipper.h" 10 | 11 | @interface ITRFlipper() 12 | { 13 | NSInteger currentPage; 14 | NSInteger numberOfPages; 15 | 16 | CALayer *backgroundLayer; 17 | CALayer *flipLayer; 18 | 19 | ITRFlipDirection flipDirection; 20 | float startFlipAngle; 21 | float endFlipAngle; 22 | float currentAngle; 23 | 24 | BOOL setNextViewOnCompletion; 25 | BOOL animating; 26 | 27 | UITapGestureRecognizer *_tapRecognizer; 28 | UIPanGestureRecognizer *_panRecognizer; 29 | 30 | UIView *_currentView; 31 | UIView *_nextView; 32 | } 33 | 34 | @end 35 | 36 | @implementation ITRFlipper 37 | 38 | #pragma init method 39 | 40 | - (id)initWithFrame:(CGRect)frame { 41 | 42 | if ((self = [super initWithFrame:frame])) { 43 | 44 | _tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)]; 45 | _panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panned:)]; 46 | 47 | [self addGestureRecognizer:_panRecognizer]; 48 | [self addGestureRecognizer:_tapRecognizer]; 49 | } 50 | return self; 51 | } 52 | 53 | - (void) initFlip { 54 | 55 | //create image from UIView 56 | UIImage *currentImage = [self imageByRenderingView:_currentView]; 57 | UIImage *newImage = [self imageByRenderingView:_nextView]; 58 | 59 | _currentView.alpha = 0; 60 | _nextView.alpha = 0; 61 | 62 | backgroundLayer = [CALayer layer]; 63 | backgroundLayer.frame = self.bounds; 64 | backgroundLayer.zPosition = -300000; 65 | 66 | //create top & bottom layer 67 | CGRect rect = self.bounds; 68 | rect.size.height /= 2; 69 | 70 | CALayer *topLayer = [CALayer layer]; 71 | topLayer.frame = rect; 72 | topLayer.masksToBounds = YES; 73 | topLayer.contentsGravity = kCAGravityBottom; 74 | 75 | [backgroundLayer addSublayer:topLayer]; 76 | 77 | rect.origin.y = rect.size.height; 78 | 79 | CALayer *bottomLayer = [CALayer layer]; 80 | bottomLayer.frame = rect; 81 | bottomLayer.masksToBounds = YES; 82 | bottomLayer.contentsGravity = kCAGravityTop; 83 | 84 | [backgroundLayer addSublayer:bottomLayer]; 85 | 86 | if (flipDirection == ITRFlipDirectionBottom) {// flip from top to bottom 87 | topLayer.contents = (id) [newImage CGImage]; 88 | bottomLayer.contents = (id) [currentImage CGImage]; 89 | } else {//flip from bottom to top 90 | topLayer.contents = (id) [currentImage CGImage]; 91 | bottomLayer.contents = (id) [newImage CGImage]; 92 | } 93 | 94 | [self.layer addSublayer:backgroundLayer]; 95 | 96 | rect.origin.y = 0; 97 | 98 | flipLayer = [CATransformLayer layer]; 99 | flipLayer.anchorPoint = CGPointMake(0.5, 1.0); 100 | flipLayer.frame = rect; 101 | 102 | [self.layer addSublayer:flipLayer]; 103 | 104 | CALayer *backLayer = [CALayer layer]; 105 | backLayer.frame = flipLayer.bounds; 106 | backLayer.doubleSided = NO; 107 | backLayer.masksToBounds = YES; 108 | 109 | [flipLayer addSublayer:backLayer]; 110 | 111 | CALayer *frontLayer = [CALayer layer]; 112 | frontLayer.frame = flipLayer.bounds; 113 | frontLayer.doubleSided = NO; 114 | frontLayer.masksToBounds = YES; 115 | frontLayer.transform = CATransform3DMakeRotation(M_PI, 1.0, 0.0, 0); 116 | 117 | [flipLayer addSublayer:frontLayer]; 118 | 119 | if (flipDirection == ITRFlipDirectionBottom) { 120 | backLayer.contents = (id) [currentImage CGImage]; 121 | backLayer.contentsGravity = kCAGravityBottom; 122 | 123 | frontLayer.contents = (id) [newImage CGImage]; 124 | frontLayer.contentsGravity = kCAGravityTop; 125 | 126 | CATransform3D transform = CATransform3DMakeRotation(0.0, 1.0, 0.0, 0.0); 127 | transform.m34 = -1.0f / 500.0f; 128 | 129 | flipLayer.transform = transform; 130 | 131 | currentAngle = startFlipAngle = 0; 132 | endFlipAngle = M_PI; 133 | } else { 134 | backLayer.contentsGravity = kCAGravityBottom; 135 | backLayer.contents = (id) [newImage CGImage]; 136 | 137 | frontLayer.contents = (id) [currentImage CGImage]; 138 | frontLayer.contentsGravity = kCAGravityTop; 139 | 140 | CATransform3D transform = CATransform3DMakeRotation(M_PI, 1.0, 0.0, 0.0); 141 | transform.m34 = 1.0f /500.0f; 142 | 143 | flipLayer.transform = transform; 144 | 145 | currentAngle = startFlipAngle = M_PI; 146 | endFlipAngle = 0; 147 | } 148 | } 149 | 150 | #pragma flip 151 | 152 | - (void) flipPage { 153 | [self setFlipProgress:1.0 setDelegate:YES animate:YES]; 154 | } 155 | 156 | - (void) setFlipProgress:(float) progress setDelegate:(BOOL) setDelegate animate:(BOOL) animate { 157 | if (animate) { 158 | animating = YES; 159 | } 160 | 161 | float angle = startFlipAngle + progress * (endFlipAngle - startFlipAngle); 162 | 163 | float duration = animate ? 0.5 * fabs((angle - currentAngle) / (endFlipAngle - startFlipAngle)) : 0; 164 | 165 | currentAngle = angle; 166 | 167 | CATransform3D finalTransform = CATransform3DIdentity; 168 | finalTransform.m34 = 1.0f / 1500.0f; 169 | finalTransform = CATransform3DRotate(finalTransform, angle, 1.0, 0.0, 0.0); 170 | 171 | [flipLayer removeAllAnimations]; 172 | 173 | [CATransaction begin]; 174 | [CATransaction setAnimationDuration:duration]; 175 | 176 | flipLayer.transform = finalTransform; 177 | 178 | [CATransaction commit]; 179 | 180 | if (setDelegate) { 181 | [self performSelector:@selector(cleanupFlip) withObject:Nil afterDelay:duration]; 182 | } 183 | } 184 | 185 | //clear flip & background layer 186 | - (void) cleanupFlip { 187 | 188 | [backgroundLayer removeFromSuperlayer]; 189 | [flipLayer removeFromSuperlayer]; 190 | 191 | backgroundLayer = Nil; 192 | flipLayer = Nil; 193 | 194 | animating = NO; 195 | 196 | if (setNextViewOnCompletion) { 197 | [_currentView removeFromSuperview]; 198 | _currentView = _nextView; 199 | _nextView = Nil; 200 | } else { 201 | [_nextView removeFromSuperview]; 202 | _nextView = Nil; 203 | } 204 | 205 | _currentView.alpha = 1; 206 | } 207 | 208 | #pragma selector 209 | 210 | - (void)animationDidStop:(NSString *) animationID finished:(NSNumber *) finished context:(void *) context { 211 | [self cleanupFlip]; 212 | } 213 | 214 | 215 | #pragma setter 216 | 217 | - (void) setCurrentPage:(NSInteger) page { 218 | 219 | if (![self canSetCurrentPage:page]) { 220 | return; 221 | } 222 | 223 | setNextViewOnCompletion = YES; 224 | animating = YES; 225 | 226 | _nextView.alpha = 0; 227 | 228 | [UIView beginAnimations:@"" context:Nil]; 229 | [UIView setAnimationDuration:0.5]; 230 | [UIView setAnimationDelegate:self]; 231 | [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; 232 | 233 | _nextView.alpha = 1; 234 | 235 | [UIView commitAnimations]; 236 | } 237 | 238 | - (void) setCurrentPage:(NSInteger) page animated:(BOOL) animated { 239 | if (![self canSetCurrentPage:page]) { 240 | return; 241 | } 242 | 243 | setNextViewOnCompletion = YES; 244 | animating = YES; 245 | 246 | if (animated) { 247 | [self initFlip]; 248 | [self performSelector:@selector(flipPage) withObject:Nil afterDelay:0.001]; 249 | } else { 250 | [self animationDidStop:Nil finished:[NSNumber numberWithBool:NO] context:Nil]; 251 | } 252 | 253 | } 254 | 255 | - (void) setDataSource:(NSObject *) dataSource { 256 | 257 | _dataSource = dataSource; 258 | numberOfPages = [_dataSource numberOfPagesinFlipper:self]; 259 | currentPage = 0; 260 | 261 | //pagecontrol current page 262 | self.currentPage = 1; 263 | } 264 | 265 | 266 | - (BOOL) canSetCurrentPage:(NSInteger) page { 267 | 268 | if (page == currentPage) { 269 | return NO; 270 | } 271 | 272 | flipDirection = page < currentPage ? ITRFlipDirectionBottom : ITRFlipDirectionTop; 273 | currentPage= page; 274 | 275 | _nextView = [self.dataSource viewForPage:page inFlipper:self]; 276 | [self addSubview:_nextView]; 277 | 278 | return YES; 279 | } 280 | 281 | #pragma Gesture recognizer handler 282 | 283 | - (void) tapped:(UITapGestureRecognizer *) recognizer { 284 | 285 | if (!animating) { 286 | if (recognizer.state == UIGestureRecognizerStateRecognized) { 287 | NSInteger newPage; 288 | 289 | if ([recognizer locationInView:self].y < (self.bounds.size.height - self.bounds.origin.y) / 2) { 290 | newPage = MAX(1, currentPage - 1); 291 | } else { 292 | newPage = MIN(currentPage + 1, numberOfPages); 293 | } 294 | 295 | [self setCurrentPage:newPage animated:YES]; 296 | } 297 | } 298 | } 299 | 300 | 301 | - (void) panned:(UIPanGestureRecognizer *) recognizer { 302 | 303 | if (!animating) { 304 | 305 | static BOOL hasFailed; 306 | static BOOL initialized; 307 | static NSInteger lastPage; 308 | 309 | float translation = [recognizer translationInView:self].y; 310 | 311 | float progress = translation / self.bounds.size.height; 312 | 313 | if (flipDirection == ITRFlipDirectionTop) { 314 | progress = MIN(progress, 0); 315 | } else { 316 | progress = MAX(progress, 0); 317 | } 318 | 319 | switch (recognizer.state) { 320 | 321 | case UIGestureRecognizerStateBegan: 322 | hasFailed = FALSE; 323 | initialized = FALSE; 324 | animating = NO; 325 | setNextViewOnCompletion = NO; 326 | break; 327 | 328 | case UIGestureRecognizerStateChanged: 329 | 330 | if (!hasFailed) { 331 | if (!initialized) { 332 | 333 | lastPage = currentPage; 334 | if (translation > 0) { 335 | if (currentPage > 1) { 336 | [self canSetCurrentPage:currentPage - 1]; 337 | } else { 338 | hasFailed = TRUE; 339 | return; 340 | } 341 | } else { 342 | if (currentPage < numberOfPages) { 343 | [self canSetCurrentPage:currentPage + 1]; 344 | } else { 345 | hasFailed = TRUE; 346 | return; 347 | } 348 | } 349 | hasFailed = NO; 350 | initialized = TRUE; 351 | setNextViewOnCompletion = NO; 352 | 353 | [self initFlip]; 354 | } 355 | [self setFlipProgress:fabs(progress) setDelegate:NO animate:NO]; 356 | } 357 | break; 358 | 359 | case UIGestureRecognizerStateFailed: 360 | [self setFlipProgress:0.0 setDelegate:YES animate:YES]; 361 | currentPage = lastPage; 362 | break; 363 | 364 | case UIGestureRecognizerStateRecognized: 365 | if (hasFailed) { 366 | [self setFlipProgress:0.0 setDelegate:YES animate:YES]; 367 | currentPage = lastPage; 368 | return; 369 | } 370 | 371 | if (fabs((translation + [recognizer velocityInView:self].y / 4) / self.bounds.size.height) > 0.5) { 372 | setNextViewOnCompletion = YES; 373 | [self setFlipProgress:1.0 setDelegate:YES animate:YES]; 374 | } else { 375 | [self setFlipProgress:0.0 setDelegate:YES animate:YES]; 376 | currentPage = lastPage; 377 | } 378 | break; 379 | 380 | default: 381 | break; 382 | } 383 | } 384 | } 385 | 386 | //return UIView as UIImage by rendering view 387 | - (UIImage *) imageByRenderingView:(UIView *)view { 388 | 389 | CGFloat viewAlpha = view.alpha; 390 | view.alpha = 1; 391 | 392 | UIGraphicsBeginImageContext(view.bounds.size); 393 | [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 394 | UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext(); 395 | UIGraphicsEndImageContext(); 396 | 397 | view.alpha = viewAlpha; 398 | return resultingImage; 399 | } 400 | 401 | @end 402 | -------------------------------------------------------------------------------- /Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ITRFlipView 4 | // 5 | // Created by kiruthika selvavinayagam on 10/15/15. 6 | // Copyright © 2015 kiruthika selvavinayagam. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ITRFlipper.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = 'ITRFlipper' 4 | s.version = '1.0.0' 5 | s.summary = 'Flipboard animation' 6 | s.homepage = 'https://github.com/ITechRoof/ITRFlipper' 7 | 8 | s.license = { :type => 'MIT', :file => 'FILE_LICENSE' } 9 | 10 | s.author = { 'Kiruthika' => 'kirthi.shalom@gmail.com' } 11 | s.platform = :ios, '7.0' 12 | s.source = { :git => 'https://github.com/ITechRoof/ITRFlipper.git', :tag => s.version.to_s } 13 | s.source_files = 'classes/*.{h,m}' 14 | s.frameworks = 'UIKit' 15 | s.requires_arc = true 16 | 17 | end 18 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '6.0' 3 | 4 | target 'Example' do 5 | 6 | end 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ITRFlipper 2 | Flipboard animation 3 | 4 | 5 | 6 | ## Requirements 7 | * Xcode 6 or higher 8 | * Apple LLVM compiler 9 | * iOS 7.0 or higher 10 | * ARC 11 | 12 | ## Demo 13 | 14 | Build and run the `Example` project in Xcode to see `ITRFlipper` in action. 15 | 16 | ## Installation 17 | 18 | ### CocoaPods 19 | 20 | The recommended approach for installating `ITRFlipper` is via the [CocoaPods](http://cocoapods.org/) package manager, as it provides flexible dependency management and dead simple installation. 21 | For best results, it is recommended that you install via CocoaPods >= **0.28.0** using Git >= **1.8.0** installed via Homebrew. 22 | 23 | Install CocoaPods if not already available: 24 | 25 | ``` bash 26 | $ [sudo] gem install cocoapods 27 | $ pod setup 28 | ``` 29 | 30 | Change to the directory of your Xcode project: 31 | 32 | ``` bash 33 | $ cd /path/to/MyProject 34 | $ touch Podfile 35 | $ edit Podfile 36 | ``` 37 | 38 | Edit your Podfile and add ITRFlipper: 39 | 40 | ``` bash 41 | platform :ios, '6.0' 42 | pod 'ITRFlipper', '~> 1.0.0' 43 | ``` 44 | 45 | Install into your Xcode project: 46 | 47 | ``` bash 48 | $ pod install 49 | ``` 50 | 51 | Open your project in Xcode from the .xcworkspace file (not the usual project file) 52 | 53 | ``` bash 54 | $ open MyProject.xcworkspace 55 | ``` 56 | 57 | Please note that if your installation fails, it may be because you are installing with a version of Git lower than CocoaPods is expecting. Please ensure that you are running Git >= **1.8.0** by executing `git --version`. You can get a full picture of the installation details by executing `pod install --verbose`. 58 | 59 | ### Manual Install 60 | 61 | All you need to do is drop `ITRFlipper` files into your project, and add `#import "ITRFlipper.h"` to the top of classes that will use it. 62 | 63 | ## Example Usage 64 | 65 | Create and add flipper view as subview to your container. Set datasource to the flipper. 66 | 67 | ``` objective-c 68 | //flipper view 69 | itrFlipper = [[ITRFlipper alloc] initWithFrame:self.view.bounds]; 70 | [itrFlipper setBackgroundColor:[UIColor clearColor]]; 71 | itrFlipper.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 72 | itrFlipper.dataSource = self; 73 | 74 | [self.view addSubview:itrFlipper]; 75 | ``` 76 | numberOfPagesinFlipper: - returns the number of pages in the flip view. 77 | 78 | ``` objective-c 79 | - (NSInteger) numberOfPagesinFlipper:(ITRFlipper *)pageFlipper { 80 | return 10; 81 | } 82 | 83 | ``` 84 | viewForPage: inFlipper: - returns the view corresponding to the page. 85 | 86 | ``` objective-c 87 | - (UIView *) viewForPage:(NSInteger) page inFlipper:(ITRFlipper *) flipper { 88 | 89 | if(page % 3 == 0){ 90 | return _firstViewController.view; 91 | }else if(page % 3 == 1){ 92 | return _secondViewController.view; 93 | }else{ 94 | return _thirdViewController.view; 95 | } 96 | } 97 | 98 | ``` 99 | 100 | ## Contact 101 | 102 | Kiruthika 103 | 104 | - https://github.com/ITechRoof 105 | - kirthi.shalom@gmail.com 106 | 107 | ## License 108 | 109 | ITRFlipper is available under the MIT license. 110 | 111 | Copyright (c) 2015 ITechRoof. 112 | 113 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 114 | 115 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 116 | 117 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 118 | 119 | 120 | --------------------------------------------------------------------------------