├── Demo ├── ObjCDemo │ ├── colorful_umbrellas.jpg │ ├── SCRootViewController.h │ ├── Helpers │ │ ├── UIColor+RandomColors.h │ │ ├── UIView+Shadows.h │ │ ├── UIColor+RandomColors.m │ │ └── UIView+Shadows.m │ ├── SCAppDelegate.h │ ├── main.m │ ├── SCAppDelegate.m │ ├── SCPageViewController-Info.plist │ ├── SCMainViewController.h │ ├── SCRootViewController.xib │ ├── Launch Screen.xib │ ├── SCRootViewController.m │ ├── SCMainViewController.xib │ └── SCMainViewController.m ├── Podfile ├── SwiftDemo │ ├── SwiftDemo-Bridging-Header.h │ ├── Supporting Files │ │ ├── Info.plist │ │ └── LaunchScreen.storyboard │ ├── MainViewController.swift │ ├── AppDelegate.swift │ ├── MainViewController.xib │ └── RootViewController.swift ├── Tests │ ├── Info.plist │ ├── SCPageViewControllerTests.m │ └── SCPageLayouterTests.m └── SCPageViewController.xcodeproj │ ├── xcshareddata │ └── xcschemes │ │ ├── Tests.xcscheme │ │ ├── SwiftDemo.xcscheme │ │ └── ObjCDemo.xcscheme │ └── project.pbxproj ├── .gitignore ├── SCPageViewController ├── Layouters │ ├── SCSlidingPageLayouter.h │ ├── SCParallaxPageLayouter.h │ ├── SCCardsPageLayouter.h │ ├── SCPageLayouter.h │ ├── SCSlidingPageLayouter.m │ ├── SCParallaxPageLayouter.m │ ├── SCCardsPageLayouter.m │ ├── SCPageLayouter.m │ └── SCPageLayouterProtocol.h ├── SCPageViewControllerView.m ├── SCPageViewControllerView.h └── SCPageViewController.h ├── LICENSE ├── SCPageViewController.podspec └── README.md /Demo/ObjCDemo/colorful_umbrellas.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefanceriu/SCPageViewController/HEAD/Demo/ObjCDemo/colorful_umbrellas.jpg -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCRootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCRootViewController.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface SCRootViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Demo/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | platform :ios, '9.0' 4 | 5 | def shared_pods 6 | pod 'SCScrollView', '~> 1.1' 7 | end 8 | 9 | target 'ObjCDemo' do 10 | shared_pods 11 | end 12 | 13 | target 'Tests' do 14 | shared_pods 15 | end 16 | 17 | target 'SwiftDemo' do 18 | shared_pods 19 | end -------------------------------------------------------------------------------- /Demo/ObjCDemo/Helpers/UIColor+RandomColors.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+RandomColors.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface UIColor (RandomColors) 12 | 13 | + (UIColor *)randomColor; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | 20 | # CocoaPods 21 | Demo/Pods/ 22 | Podfile.lock 23 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCAppDelegate.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 10/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SCAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Demo/SwiftDemo/SwiftDemo-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "SCPageViewController.h" 6 | 7 | #import "SCCardsPageLayouter.h" 8 | #import "SCPageLayouter.h" 9 | #import "SCParallaxPageLayouter.h" 10 | #import "SCSlidingPageLayouter.h" 11 | 12 | #import "SCScrollView.h" 13 | #import "SCEasingFunction.h" 14 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCSlidingPageLayouter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCSlidingPageLayouter.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCPageLayouter.h" 10 | 11 | /** A SCPageLayouter subclass that adds a sliding effect when navigating between pages */ 12 | @interface SCSlidingPageLayouter : SCPageLayouter 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCParallaxPageLayouter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCParallaxPageLayouter.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCPageLayouter.h" 10 | 11 | /** A SCPageLayouter subclass that adds a parallax effect when navigating between pages */ 12 | @interface SCParallaxPageLayouter : SCPageLayouter 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 10/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SCAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SCAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCCardsPageLayouter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCCardsPageLayouter.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 23/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCPageLayouter.h" 10 | 11 | /** 12 | * A SCPageLayouter subclass that shrinks the page sizes 13 | * to a percentage of the page view controller bounds and 14 | * centers them on screen 15 | */ 16 | @interface SCCardsPageLayouter : SCPageLayouter 17 | 18 | @property (nonatomic, assign) CGFloat pagePercentage; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /SCPageViewController/SCPageViewControllerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCPageViewControllerView.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 18/01/2015. 6 | // Copyright (c) 2015 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCPageViewControllerView.h" 10 | 11 | @implementation SCPageViewControllerView 12 | 13 | - (void)setFrame:(CGRect)frame 14 | { 15 | [self.delegate pageViewControllerViewWillChangeFrame:self]; 16 | 17 | super.frame = frame; 18 | 19 | [self.delegate pageViewControllerViewDidChangeFrame:self]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCPageLayouter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCPageLayouter.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCPageLayouterProtocol.h" 10 | 11 | /** 12 | * A page layouter that can show pages side by side, horizontally or vertically. 13 | * It defines simple incremental update animations and supports inter-item spacings. 14 | */ 15 | @interface SCPageLayouter : NSObject 16 | 17 | @property (nonatomic, assign) CGFloat interItemSpacing; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/Helpers/UIView+Shadows.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Shadows.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | typedef enum { 12 | SCShadowEdgeNone = 0, 13 | SCShadowEdgeTop = 1 << 0, 14 | SCShadowEdgeLeft = 1 << 1, 15 | SCShadowEdgeBottom = 1 << 2, 16 | SCShadowEdgeRight = 1 << 3, 17 | SCShadowEdgeAll = SCShadowEdgeTop | SCShadowEdgeLeft | SCShadowEdgeBottom | SCShadowEdgeRight 18 | } SCShadowEdge; 19 | 20 | @interface UIView (Shadows) 21 | 22 | - (void)castShadowWithPosition:(SCShadowEdge)edge; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/Helpers/UIColor+RandomColors.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+RandomColors.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "UIColor+RandomColors.h" 10 | 11 | @implementation UIColor (RandomColors) 12 | 13 | + (UIColor *)randomColor 14 | { 15 | CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0 16 | CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white 17 | CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black 18 | return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCAppDelegate.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 10/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCAppDelegate.h" 10 | #import "SCRootViewController.h" 11 | 12 | @implementation SCAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 17 | self.window.rootViewController = [[SCRootViewController alloc] initWithNibName:NSStringFromClass([SCRootViewController class]) bundle:nil]; 18 | [self.window makeKeyAndVisible]; 19 | return YES; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Demo/Tests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SCPageViewController/SCPageViewControllerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCPageViewControllerView.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 18/01/2015. 6 | // Copyright (c) 2015 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @protocol SCPageViewControllerViewDelegate; 12 | 13 | /** A custom view used inside the page view controller 14 | * which notifies it about impending frame changes 15 | */ 16 | @interface SCPageViewControllerView : UIView 17 | 18 | /** The pageViewControllerView's delegate */ 19 | @property (nonatomic, weak) id delegate; 20 | 21 | @end 22 | 23 | /** The pageViewControllerView's delegate protocol */ 24 | @protocol SCPageViewControllerViewDelegate 25 | 26 | /** Called when the view's frame is about to be changed */ 27 | - (void)pageViewControllerViewWillChangeFrame:(SCPageViewControllerView *)pageViewControllerView; 28 | 29 | /** Called after the view's frame has been changed */ 30 | - (void)pageViewControllerViewDidChangeFrame:(SCPageViewControllerView *)pageViewControllerView; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) [2013] [Stefan Ceriu] 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | 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, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | 24 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCSlidingPageLayouter.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCSlidingPageLayouter.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCSlidingPageLayouter.h" 10 | 11 | @implementation SCSlidingPageLayouter 12 | 13 | - (id)init 14 | { 15 | if(self = [super init]) { 16 | self.interItemSpacing = 0.0f; 17 | } 18 | 19 | return self; 20 | } 21 | 22 | - (CGRect)currentFrameForPageAtIndex:(NSUInteger)index 23 | contentOffset:(CGPoint)contentOffset 24 | finalFrame:(CGRect)finalFrame 25 | pageViewController:(SCPageViewController *)pageViewController 26 | { 27 | if(index == 0) { 28 | return finalFrame; 29 | } 30 | 31 | if(self.navigationType == SCPageLayouterNavigationTypeVertical) { 32 | finalFrame.origin.y = MAX(finalFrame.origin.y - finalFrame.size.height, MIN(CGRectGetMaxY(finalFrame) - CGRectGetHeight(finalFrame), contentOffset.y)); 33 | } else { 34 | finalFrame.origin.x = MAX(finalFrame.origin.x - finalFrame.size.width, MIN(CGRectGetMaxX(finalFrame) - CGRectGetWidth(finalFrame), contentOffset.x)); 35 | } 36 | 37 | return finalFrame; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/Helpers/UIView+Shadows.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Shadows.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "UIView+Shadows.h" 10 | #import 11 | 12 | static const CGFloat shadowSize = 10; 13 | 14 | @implementation UIView (Shadows) 15 | 16 | - (void)castShadowWithPosition:(SCShadowEdge)position; 17 | { 18 | if(position == SCShadowEdgeNone) { 19 | self.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectZero].CGPath; 20 | return; 21 | } 22 | 23 | CGRect shadowRect = self.bounds; 24 | 25 | if(position & SCShadowEdgeTop) { 26 | shadowRect.origin.y -= shadowSize; 27 | shadowRect.size.height += shadowSize; 28 | } 29 | 30 | if(position & SCShadowEdgeLeft) { 31 | shadowRect.origin.x -= shadowSize; 32 | shadowRect.size.width += shadowSize; 33 | } 34 | 35 | if(position & SCShadowEdgeBottom) { 36 | shadowRect.size.height += shadowSize; 37 | } 38 | 39 | if(position & SCShadowEdgeRight) { 40 | shadowRect.size.width += shadowSize; 41 | } 42 | 43 | self.layer.masksToBounds = NO; 44 | self.layer.shadowRadius = 5; 45 | self.layer.shadowOffset = CGSizeZero; 46 | self.layer.shadowOpacity = 0.25; 47 | 48 | self.layer.shadowPath = [UIBezierPath bezierPathWithRect:shadowRect].CGPath; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCParallaxPageLayouter.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCParallaxPageLayouter.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCParallaxPageLayouter.h" 10 | 11 | @implementation SCParallaxPageLayouter 12 | 13 | - (id)init 14 | { 15 | if(self = [super init]) { 16 | self.interItemSpacing = 0.0f; 17 | } 18 | 19 | return self; 20 | } 21 | 22 | - (CGRect)currentFrameForPageAtIndex:(NSUInteger)index 23 | contentOffset:(CGPoint)contentOffset 24 | finalFrame:(CGRect)finalFrame 25 | pageViewController:(SCPageViewController *)pageViewController 26 | { 27 | if(index == 0) { 28 | return finalFrame; 29 | } 30 | 31 | if(self.navigationType == SCPageLayouterNavigationTypeVertical) { 32 | CGFloat ratio = 1.0f - (CGRectGetMinY(finalFrame) - contentOffset.y) / (CGRectGetHeight(finalFrame) + CGRectGetHeight(finalFrame)/2); 33 | finalFrame.origin.y = (CGRectGetMinY(finalFrame) - CGRectGetHeight(finalFrame)) + CGRectGetHeight(finalFrame) * MAX(0.0f, MIN(1.0f, ratio)); 34 | } else { 35 | CGFloat ratio = 1.0f - (CGRectGetMinX(finalFrame) - contentOffset.x) / (CGRectGetWidth(finalFrame) + CGRectGetWidth(finalFrame)/2); 36 | finalFrame.origin.x = (CGRectGetMinX(finalFrame) - CGRectGetWidth(finalFrame)) + CGRectGetWidth(finalFrame) * MAX(0.0f, MIN(1.0f, ratio)); 37 | } 38 | 39 | return finalFrame; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Demo/SwiftDemo/Supporting Files/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 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCPageViewController-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | Launch Screen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationPortraitUpsideDown 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | UISupportedInterfaceOrientations~ipad 41 | 42 | UIInterfaceOrientationLandscapeRight 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Demo/SwiftDemo/Supporting Files/LaunchScreen.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 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCMainViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCMainViewController.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | #import "SCEasingFunction.h" 12 | 13 | typedef enum { 14 | SCPageLayouterTypePlain, 15 | SCPageLayouterTypeSliding, 16 | SCPageLayouterTypeParallax, 17 | SCPageLayouterTypeCards, 18 | SCPageLayouterTypeCount 19 | } SCPageLayouterType; 20 | 21 | @protocol SCMainViewControllerDelegate; 22 | 23 | @interface SCMainViewController : UIViewController 24 | 25 | @property (nonatomic, weak, readonly) UIView *contentView; 26 | 27 | @property (nonatomic, weak, readonly) UILabel *pageNumberLabel; 28 | @property (nonatomic, weak, readonly) UILabel *visiblePercentageLabel; 29 | 30 | @property (nonatomic, weak) IBOutlet id delegate; 31 | 32 | @property (nonatomic, assign) SCPageLayouterType layouterType; 33 | @property (nonatomic, assign) SCEasingFunctionType easingFunctionType; 34 | @property (nonatomic, assign) NSTimeInterval duration; 35 | 36 | @end 37 | 38 | @protocol SCMainViewControllerDelegate 39 | 40 | - (void)mainViewControllerDidChangeLayouterType:(SCMainViewController *)mainViewController; 41 | 42 | - (void)mainViewControllerDidChangeAnimationType:(SCMainViewController *)mainViewController; 43 | 44 | - (void)mainViewControllerDidChangeAnimationDuration:(SCMainViewController *)mainViewController; 45 | 46 | - (void)mainViewControllerDidRequestNavigationToPreviousPage:(SCMainViewController *)mainViewController; 47 | 48 | - (void)mainViewControllerDidRequestNavigationToNextPage:(SCMainViewController *)mainViewController; 49 | 50 | - (void)mainViewControllerDidRequestPageInsertion:(SCMainViewController *)mainViewController; 51 | 52 | - (void)mainViewControllerDidRequestPageDeletion:(SCMainViewController *)mainViewController; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /SCPageViewController.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SCPageViewController' 3 | s.version = '2.0.14' 4 | s.platform = :ios 5 | s.ios.deployment_target = '6.0' 6 | 7 | s.summary = 'SCPageViewController is a container view controller similar to UIPageViewController which provies more control and is much more customizable' 8 | s.description = <<-DESC 9 | SCPageViewController is a container view controller similar to UIPageViewController but which provies more control, is much more customizable and, arguably, has a better overall design. 10 | It supports the following features: 11 | 12 | - Customizable transitions and animations (through layouters and custom easing functions) 13 | - Incremental updates with user defined animations 14 | - Bouncing and realistic physics 15 | - Correct appearance calls, even while interactions are in progres 16 | - Custom layouts and animated layout changes 17 | - Vertical and horizontal layouts 18 | - Pagination 19 | - Content insets 20 | - Completion blocks 21 | - Customizable interaction area and number of touches required 22 | 23 | and more.. 24 | DESC 25 | s.homepage = 'https://github.com/stefanceriu/SCPageViewController' 26 | s.author = { 'Stefan Ceriu' => 'stefan.ceriu@yahoo.com' } 27 | s.social_media_url = 'https://twitter.com/stefanceriu' 28 | s.source = { :git => 'https://github.com/stefanceriu/SCPageViewController.git', :tag => "v#{s.version}" } 29 | s.license = { :type => 'MIT License', :file => 'LICENSE' } 30 | s.source_files = 'SCPageViewController/*', 'SCPageViewController/Layouters/*' 31 | s.requires_arc = true 32 | s.frameworks = 'UIKit', 'QuartzCore', 'CoreGraphics', 'Foundation' 33 | 34 | s.dependency 'SCScrollView', '~> 1.1' 35 | 36 | end 37 | -------------------------------------------------------------------------------- /Demo/SwiftDemo/MainViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.swift 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 12/6/15. 6 | // Copyright © 2015 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol MainViewControllerDelegate { 12 | func mainViewControllerDidChangeLayouterType(_ mainViewController: MainViewController) 13 | } 14 | 15 | enum PageLayouterType : Int { 16 | case plain, sliding, parallax, cards 17 | } 18 | 19 | class MainViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate { 20 | 21 | @IBOutlet var pickerView:UIPickerView! 22 | 23 | var delegate:MainViewControllerDelegate? 24 | var layouterType:PageLayouterType? { 25 | didSet { 26 | pickerView.selectRow(layouterType!.rawValue, inComponent: 0, animated: false) 27 | } 28 | } 29 | 30 | override func viewDidLoad() { 31 | super.viewDidLoad() 32 | } 33 | 34 | func numberOfComponents(in pickerView: UIPickerView) -> Int { 35 | return 1 36 | } 37 | 38 | func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 39 | return 4 40 | } 41 | 42 | func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 43 | 44 | let layouterType = PageLayouterType.init(rawValue: row)! 45 | switch(layouterType) { 46 | case .plain: 47 | return "Plain" 48 | case .sliding: 49 | return "Sliding" 50 | case .parallax: 51 | return "Parallax" 52 | case .cards: 53 | return "Cards" 54 | } 55 | } 56 | 57 | func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 58 | layouterType = PageLayouterType.init(rawValue: row)! 59 | delegate?.mainViewControllerDidChangeLayouterType(self) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCRootViewController.xib: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /Demo/SwiftDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SwiftDemo 4 | // 5 | // Created by Stefan Ceriu on 10/14/15. 6 | // Copyright © 2015 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | 20 | self.window = UIWindow(frame: UIScreen.main.bounds) 21 | self.window?.rootViewController = RootViewController() 22 | self.window?.makeKeyAndVisible() 23 | 24 | return true 25 | } 26 | 27 | func applicationWillResignActive(_ application: UIApplication) { 28 | // 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. 29 | // 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. 30 | } 31 | 32 | func applicationDidEnterBackground(_ application: UIApplication) { 33 | // 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. 34 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 35 | } 36 | 37 | func applicationWillEnterForeground(_ application: UIApplication) { 38 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 39 | } 40 | 41 | func applicationDidBecomeActive(_ application: UIApplication) { 42 | // 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. 43 | } 44 | 45 | func applicationWillTerminate(_ application: UIApplication) { 46 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Demo/SCPageViewController.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 12 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 53 | 54 | 55 | 61 | 62 | 64 | 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCCardsPageLayouter.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCCardsPageLayouter.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 23/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCCardsPageLayouter.h" 10 | 11 | @implementation SCCardsPageLayouter 12 | @synthesize navigationType; 13 | @synthesize numberOfPagesToPreloadBeforeCurrentPage; 14 | @synthesize numberOfPagesToPreloadAfterCurrentPage; 15 | @synthesize navigationConstraintType; 16 | 17 | - (instancetype)init 18 | { 19 | if(self = [super init]) { 20 | 21 | self.numberOfPagesToPreloadBeforeCurrentPage = 3; 22 | self.numberOfPagesToPreloadAfterCurrentPage = 3; 23 | 24 | self.navigationConstraintType = SCPageLayouterNavigationContraintTypeForward | SCPageLayouterNavigationContraintTypeReverse; 25 | 26 | self.pagePercentage = 0.5f; 27 | } 28 | 29 | return self; 30 | } 31 | 32 | - (UIEdgeInsets)contentInsetForPageViewController:(SCPageViewController *)pageViewController 33 | { 34 | CGRect frame = pageViewController.view.bounds; 35 | CGFloat verticalInset = floor(CGRectGetHeight(frame) - CGRectGetHeight(frame) * self.pagePercentage); 36 | CGFloat horizontalInset = floor(CGRectGetWidth(frame) - CGRectGetWidth(frame) * self.pagePercentage); 37 | 38 | return UIEdgeInsetsMake(verticalInset/2.0f, horizontalInset/2.0f, verticalInset/2.0f, horizontalInset/2.0f); 39 | } 40 | 41 | - (CGFloat)interItemSpacingForPageViewController:(SCPageViewController *)pageViewController 42 | { 43 | switch (self.navigationType) { 44 | case SCPageLayouterNavigationTypeHorizontal: { 45 | self.interItemSpacing = floor(CGRectGetWidth(pageViewController.view.bounds)/100.0f); 46 | } 47 | case SCPageLayouterNavigationTypeVertical: { 48 | self.interItemSpacing = floor(CGRectGetHeight(pageViewController.view.bounds)/100.0f); 49 | } 50 | } 51 | 52 | return self.interItemSpacing; 53 | } 54 | 55 | - (CGRect)finalFrameForPageAtIndex:(NSUInteger)index 56 | pageViewController:(SCPageViewController *)pageViewController 57 | { 58 | CGRect frame = pageViewController.view.bounds; 59 | frame.size.height = frame.size.height * self.pagePercentage; 60 | frame.size.width = frame.size.width * self.pagePercentage; 61 | 62 | if(self.navigationType == SCPageLayouterNavigationTypeVertical) { 63 | frame.origin.y = index * (CGRectGetHeight(frame) + self.interItemSpacing); 64 | frame.origin.x = CGRectGetMidX(pageViewController.view.bounds) - CGRectGetMidX(frame); 65 | } else { 66 | frame.origin.x = index * (CGRectGetWidth(frame) + self.interItemSpacing); 67 | frame.origin.y = CGRectGetMidY(pageViewController.view.bounds) - CGRectGetMidY(frame); 68 | } 69 | 70 | return frame; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Demo/SCPageViewController.xcodeproj/xcshareddata/xcschemes/SwiftDemo.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 | -------------------------------------------------------------------------------- /Demo/SwiftDemo/MainViewController.xib: -------------------------------------------------------------------------------- 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 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/Launch Screen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Demo/Tests/SCPageViewControllerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCPageViewControllerTests.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 6/21/15. 6 | // Copyright (c) 2015 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "SCPageViewController.h" 13 | #import "SCPageLayouter.h" 14 | 15 | static NSUInteger const kDefaultNumberOfPages = 10; 16 | 17 | @interface SCPageViewControllerTests : XCTestCase 18 | 19 | @property (nonatomic, strong) SCPageViewController *pageViewController; 20 | @property (nonatomic, strong) id layouter; 21 | @property (nonatomic, strong) NSMutableArray *viewControllers; 22 | 23 | @end 24 | 25 | @implementation SCPageViewControllerTests 26 | 27 | - (void)setUp 28 | { 29 | [super setUp]; 30 | 31 | self.viewControllers = [NSMutableArray array]; 32 | for(int i=0; i<10; i++) { 33 | [self.viewControllers addObject:[NSNull null]]; 34 | } 35 | 36 | self.pageViewController = [[SCPageViewController alloc] init]; 37 | [self.pageViewController setDataSource:self]; 38 | 39 | self.layouter = [[SCPageLayouter alloc] init]; 40 | [self.pageViewController setLayouter:self.layouter animated:NO completion:nil]; 41 | 42 | UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController; 43 | 44 | [self.pageViewController willMoveToParentViewController:rootViewController]; 45 | 46 | [rootViewController addChildViewController:self.pageViewController]; 47 | 48 | [rootViewController.view addSubview:self.pageViewController.view]; 49 | [self.pageViewController.view setFrame:rootViewController.view.bounds]; 50 | 51 | [self.pageViewController didMoveToParentViewController:rootViewController]; 52 | } 53 | 54 | - (void)tearDown 55 | { 56 | [super tearDown]; 57 | 58 | [self.pageViewController willMoveToParentViewController:nil]; 59 | [self.pageViewController.view removeFromSuperview]; 60 | [self.pageViewController removeFromParentViewController]; 61 | } 62 | 63 | - (void)testStartupProperties_01 64 | { 65 | XCTAssert(CGRectEqualToRect(self.pageViewController.view.bounds, [UIScreen mainScreen].bounds)); 66 | XCTAssert(self.pageViewController.numberOfPages == 10); 67 | XCTAssert(self.pageViewController.currentPage == 0); 68 | XCTAssert(self.pageViewController.loadedViewControllers.count == 2); 69 | } 70 | 71 | - (void)testNavigation_01 72 | { 73 | [self.pageViewController navigateToPageAtIndex:1 animated:NO completion:nil]; 74 | 75 | XCTAssert(self.pageViewController.currentPage == 1); 76 | XCTAssert(self.pageViewController.visibleViewControllers.count == 1); 77 | XCTAssert([self.pageViewController.visibleViewControllers.firstObject isEqual:self.viewControllers[self.pageViewController.currentPage]]); 78 | 79 | [self.pageViewController navigateToPageAtIndex:3 animated:NO completion:nil]; 80 | 81 | XCTAssert(self.pageViewController.currentPage == 3); 82 | XCTAssert(self.pageViewController.visibleViewControllers.count == 1); 83 | XCTAssert([self.pageViewController.visibleViewControllers.firstObject isEqual:self.viewControllers[self.pageViewController.currentPage]]); 84 | XCTAssert(self.pageViewController.loadedViewControllers.count == 3); 85 | } 86 | 87 | - (void)testNavigation_02 88 | { 89 | [self.pageViewController navigateToPageAtIndex:(self.pageViewController.numberOfPages - 1) animated:NO completion:nil]; 90 | 91 | XCTAssert(self.pageViewController.currentPage == (self.pageViewController.numberOfPages - 1)); 92 | XCTAssert(self.pageViewController.visibleViewControllers.count == 1); 93 | XCTAssert([self.pageViewController.visibleViewControllers.firstObject isEqual:self.viewControllers[self.pageViewController.currentPage]]); 94 | XCTAssert(self.pageViewController.loadedViewControllers.count == 2); 95 | } 96 | 97 | #pragma mark - SCPageViewControllerDataSource 98 | 99 | - (NSUInteger)numberOfPagesInPageViewController:(SCPageViewController *)pageViewController 100 | { 101 | return kDefaultNumberOfPages; 102 | } 103 | 104 | - (UIViewController *)pageViewController:(SCPageViewController *)pageViewController 105 | viewControllerForPageAtIndex:(NSUInteger)pageIndex 106 | { 107 | UIViewController *viewController = self.viewControllers[pageIndex]; 108 | 109 | if(!viewController || [viewController isEqual:[NSNull null]]) { 110 | viewController = [[UIViewController alloc] init]; 111 | [self.viewControllers replaceObjectAtIndex:pageIndex withObject:viewController]; 112 | } 113 | 114 | return viewController; 115 | } 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /Demo/SwiftDemo/RootViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RootViewController.swift 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 10/14/15. 6 | // Copyright © 2015 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class RootViewController : UIViewController , SCPageViewControllerDataSource, SCPageViewControllerDelegate, MainViewControllerDelegate { 12 | 13 | var pageViewController : SCPageViewController = SCPageViewController() 14 | var viewControllers = [UIViewController?]() 15 | 16 | override func viewDidLoad() { 17 | 18 | super.viewDidLoad() 19 | 20 | for _ in 1...5 { 21 | viewControllers.append(nil); 22 | } 23 | 24 | self.pageViewController.setLayouter(SCPageLayouter(), animated: false, completion: nil) 25 | self.pageViewController.easingFunction = SCEasingFunction(type: SCEasingFunctionType.linear) 26 | 27 | //self.pageViewController.scrollView.maximumNumberOfTouches = 1; 28 | //self.pageViewController.scrollView.panGestureRecognizer.minimumNumberOfTouches = 2; 29 | 30 | self.pageViewController.dataSource = self; 31 | self.pageViewController.delegate = self; 32 | 33 | self.addChildViewController(self.pageViewController) 34 | self.pageViewController.view.frame = self.view.bounds 35 | self.view.addSubview(self.pageViewController.view) 36 | self.pageViewController.didMove(toParentViewController: self) 37 | } 38 | 39 | //MARK: - SCPageViewControllerDataSource 40 | 41 | func numberOfPages(in pageViewController: SCPageViewController!) -> UInt { 42 | return UInt(self.viewControllers.count) 43 | } 44 | 45 | func pageViewController(_ pageViewController: SCPageViewController!, viewControllerForPageAt pageIndex: UInt) -> UIViewController! { 46 | 47 | 48 | if let viewController = self.viewControllers[Int(pageIndex)] { 49 | return viewController 50 | } else { 51 | let viewController = MainViewController() 52 | viewController.delegate = self; 53 | 54 | func randomColor () -> UIColor { 55 | let hue = CGFloat(arc4random() % 256) / 256.0; // 0.0 to 1.0 56 | let saturation = (CGFloat(arc4random() % 128) / 256.0 ) + 0.5 // 0.5 to 1.0, away from white 57 | let brightness = (CGFloat(arc4random() % 128) / 256.0 ) + 0.5 // 0.5 to 1.0, away from black 58 | 59 | return UIColor.init(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0); 60 | } 61 | 62 | viewController.view.backgroundColor = randomColor() 63 | viewController.view.frame = self.view.bounds; 64 | self.viewControllers[Int(pageIndex)] = viewController 65 | return viewController 66 | } 67 | } 68 | 69 | //MARK: - SCPageViewControllerDelegate 70 | 71 | func pageViewController(_ pageViewController: SCPageViewController!, didNavigateToOffset offset: CGPoint) { 72 | 73 | func layouterToType(layouter: SCPageLayouterProtocol) -> PageLayouterType { 74 | switch layouter { 75 | case is SCSlidingPageLayouter: 76 | return PageLayouterType.sliding 77 | case is SCParallaxPageLayouter: 78 | return PageLayouterType.parallax 79 | case is SCCardsPageLayouter: 80 | return PageLayouterType.cards 81 | default: 82 | return PageLayouterType.plain 83 | } 84 | } 85 | 86 | let layouterType = layouterToType(layouter: self.pageViewController.layouter!); 87 | 88 | for optionalValue in self.viewControllers { 89 | if(optionalValue != nil) { 90 | let viewController = optionalValue as! MainViewController 91 | viewController.layouterType = layouterType; 92 | } 93 | 94 | } 95 | } 96 | 97 | //MARK: - MainViewControllerDelegate 98 | 99 | func mainViewControllerDidChangeLayouterType(_ mainViewController: MainViewController) { 100 | switch(mainViewController.layouterType!) { 101 | case .plain: 102 | self.pageViewController.setLayouter(SCPageLayouter(), animated: false, completion: nil) 103 | case .sliding: 104 | self.pageViewController.setLayouter(SCSlidingPageLayouter(), animated: true, completion: nil) 105 | case .parallax: 106 | self.pageViewController.setLayouter(SCParallaxPageLayouter(), animated: true, completion: nil) 107 | case .cards: 108 | self.pageViewController.setLayouter(SCCardsPageLayouter(), animated: true, completion: nil) 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Demo/SCPageViewController.xcodeproj/xcshareddata/xcschemes/ObjCDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCPageLayouter.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCPageLayouter.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCPageLayouter.h" 10 | 11 | @interface SCPageLayouter () 12 | 13 | @end 14 | 15 | @implementation SCPageLayouter 16 | @synthesize navigationType; 17 | @synthesize numberOfPagesToPreloadBeforeCurrentPage; 18 | @synthesize numberOfPagesToPreloadAfterCurrentPage; 19 | @synthesize navigationConstraintType; 20 | 21 | - (id)init 22 | { 23 | if(self = [super init]) { 24 | 25 | self.navigationType = SCPageLayouterNavigationTypeHorizontal; 26 | self.navigationConstraintType = SCPageLayouterNavigationContraintTypeForward | SCPageLayouterNavigationContraintTypeReverse; 27 | 28 | self.numberOfPagesToPreloadBeforeCurrentPage = 1; 29 | self.numberOfPagesToPreloadAfterCurrentPage = 1; 30 | 31 | self.interItemSpacing = 50.0f; 32 | } 33 | 34 | return self; 35 | } 36 | 37 | - (CGFloat)interItemSpacingForPageViewController:(SCPageViewController *)pageViewController 38 | { 39 | return self.interItemSpacing; 40 | } 41 | 42 | - (CGRect)finalFrameForPageAtIndex:(NSUInteger)index 43 | pageViewController:(SCPageViewController *)pageViewController 44 | { 45 | CGRect frame = pageViewController.view.bounds; 46 | 47 | if(self.navigationType == SCPageLayouterNavigationTypeVertical) { 48 | frame.origin.y = index * (CGRectGetHeight(frame) + self.interItemSpacing); 49 | } else { 50 | frame.origin.x = index * (CGRectGetWidth(frame) + self.interItemSpacing); 51 | } 52 | 53 | return frame; 54 | } 55 | 56 | - (void)animatePageReloadAtIndex:(NSUInteger)index 57 | oldViewController:(UIViewController *)oldViewController 58 | newViewController:(UIViewController *)newViewController 59 | pageViewController:(SCPageViewController *)pageViewController 60 | completion:(void (^)(void))completion 61 | { 62 | [newViewController.view setAlpha:0.0f]; 63 | [UIView animateWithDuration:pageViewController.animationDuration delay:0.0f options:UIViewAnimationOptionAllowUserInteraction animations:^{ 64 | [oldViewController.view setAlpha:0.0f]; 65 | [newViewController.view setAlpha:1.0f]; 66 | } completion:^(BOOL finished) { 67 | completion(); 68 | }]; 69 | } 70 | 71 | - (void)animatePageInsertionAtIndex:(NSUInteger)index 72 | viewController:(UIViewController *)viewController 73 | pageViewController:(SCPageViewController *)pageViewController 74 | completion:(void (^)(void))completion 75 | { 76 | CGRect frame = viewController.view.frame; 77 | 78 | if(self.navigationType == SCPageLayouterNavigationTypeHorizontal) { 79 | [viewController.view setFrame:CGRectOffset(frame, 0.0f, CGRectGetHeight(frame))]; 80 | } else { 81 | [viewController.view setFrame:CGRectOffset(frame, CGRectGetWidth(frame), 0.0f)]; 82 | } 83 | 84 | [viewController.view setAlpha:0.0f]; 85 | 86 | [UIView animateWithDuration:pageViewController.animationDuration delay:0.0f options:UIViewAnimationOptionAllowUserInteraction animations:^{ 87 | [viewController.view setFrame:frame]; 88 | [viewController.view setAlpha:1.0f]; 89 | } completion:^(BOOL finished) { 90 | completion(); 91 | }]; 92 | } 93 | 94 | - (BOOL)shouldPreserveOffsetForInsertionAtIndex:(NSUInteger)index pageViewController:(SCPageViewController *)pageViewController 95 | { 96 | return YES; 97 | } 98 | 99 | - (void)animatePageDeletionAtIndex:(NSUInteger)index 100 | viewController:(UIViewController *)viewController 101 | pageViewController:(SCPageViewController *)pageViewController 102 | completion:(void (^)(void))completion 103 | { 104 | [UIView animateWithDuration:pageViewController.animationDuration delay:0.0f options:UIViewAnimationOptionAllowUserInteraction animations:^{ 105 | 106 | if(self.navigationType == SCPageLayouterNavigationTypeHorizontal) { 107 | [viewController.view setFrame:CGRectOffset(viewController.view.frame, 0.0f, CGRectGetHeight(viewController.view.bounds))]; 108 | } else { 109 | [viewController.view setFrame:CGRectOffset(viewController.view.frame, CGRectGetWidth(viewController.view.bounds), 0.0f)]; 110 | } 111 | 112 | [viewController.view setAlpha:0.0f]; 113 | } completion:^(BOOL finished) { 114 | completion(); 115 | }]; 116 | } 117 | 118 | - (void)animatePageMoveFromIndex:(NSUInteger)fromIndex 119 | toIndex:(NSUInteger)toIndex 120 | viewController:(UIViewController *)viewController 121 | pageViewController:(SCPageViewController *)pageViewController 122 | completion:(void (^)(void))completion 123 | { 124 | CGRect finalFrame = [self finalFrameForPageAtIndex:toIndex pageViewController:pageViewController]; 125 | 126 | [UIView animateWithDuration:pageViewController.animationDuration delay:0.0f options:UIViewAnimationOptionAllowUserInteraction animations:^{ 127 | [viewController.view setFrame:finalFrame]; 128 | } completion:^(BOOL finished) { 129 | completion(); 130 | }]; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /Demo/Tests/SCPageLayouterTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Tests.m 3 | // Tests 4 | // 5 | // Created by Stefan Ceriu on 6/21/15. 6 | // Copyright (c) 2015 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import "SCPageLayouter.h" 13 | 14 | @interface SCPageLayouterTests : XCTestCase 15 | 16 | @property (nonatomic, strong) SCPageViewController *pageViewController; 17 | @property (nonatomic, strong) SCPageLayouter *pageLayouter; 18 | 19 | @end 20 | 21 | @implementation SCPageLayouterTests 22 | 23 | - (void)setUp 24 | { 25 | [super setUp]; 26 | 27 | self.pageViewController = [[SCPageViewController alloc] init]; 28 | [self.pageViewController.view setFrame:CGRectMake(0, 0, 1024, 768)]; 29 | 30 | self.pageLayouter = [[SCPageLayouter alloc] init]; 31 | } 32 | 33 | - (void)testHorizontalPageFrame_01 34 | { 35 | [self.pageLayouter setInterItemSpacing:0.0f]; 36 | 37 | CGRect finalFrame = [self.pageLayouter finalFrameForPageAtIndex:0 pageViewController:self.pageViewController]; 38 | CGRect expectedFrame = CGRectMake(0, 0, CGRectGetWidth(self.pageViewController.view.bounds), CGRectGetHeight(self.pageViewController.view.bounds)); 39 | 40 | XCTAssert(CGRectEqualToRect(finalFrame, expectedFrame)); 41 | } 42 | 43 | - (void)testHorizontalPageFrame_02 44 | { 45 | [self.pageLayouter setInterItemSpacing:-100.0f]; 46 | 47 | CGRect finalFrame = [self.pageLayouter finalFrameForPageAtIndex:1 pageViewController:self.pageViewController]; 48 | CGRect expectedFrame = CGRectMake(CGRectGetWidth(self.pageViewController.view.bounds) + self.pageLayouter.interItemSpacing, 49 | 0, 50 | CGRectGetWidth(self.pageViewController.view.bounds), 51 | CGRectGetHeight(self.pageViewController.view.bounds)); 52 | 53 | XCTAssert(CGRectEqualToRect(finalFrame, expectedFrame)); 54 | } 55 | 56 | - (void)testHorizontalPageFrame_03 57 | { 58 | [self.pageLayouter setInterItemSpacing:10.0f]; 59 | 60 | CGRect finalFrame = [self.pageLayouter finalFrameForPageAtIndex:1 pageViewController:self.pageViewController]; 61 | CGRect expectedFrame = CGRectMake(CGRectGetWidth(self.pageViewController.view.bounds) + self.pageLayouter.interItemSpacing, 62 | 0, 63 | CGRectGetWidth(self.pageViewController.view.bounds), 64 | CGRectGetHeight(self.pageViewController.view.bounds)); 65 | 66 | XCTAssert(CGRectEqualToRect(finalFrame, expectedFrame)); 67 | } 68 | 69 | - (void)testHorizontalPageFrame_04 70 | { 71 | [self.pageLayouter setInterItemSpacing:123.0f]; 72 | 73 | NSUInteger pageIndex = 123; 74 | 75 | CGRect finalFrame = [self.pageLayouter finalFrameForPageAtIndex:123 pageViewController:self.pageViewController]; 76 | CGRect expectedFrame = CGRectMake((CGRectGetWidth(self.pageViewController.view.bounds) + self.pageLayouter.interItemSpacing) * pageIndex, 77 | 0, 78 | CGRectGetWidth(self.pageViewController.view.bounds), 79 | CGRectGetHeight(self.pageViewController.view.bounds)); 80 | 81 | XCTAssert(CGRectEqualToRect(finalFrame, expectedFrame)); 82 | } 83 | 84 | - (void)testVerticalPageFrame_01 85 | { 86 | [self.pageLayouter setNavigationType:SCPageLayouterNavigationTypeVertical]; 87 | [self.pageLayouter setInterItemSpacing:0.0f]; 88 | 89 | CGRect finalFrame = [self.pageLayouter finalFrameForPageAtIndex:0 pageViewController:self.pageViewController]; 90 | CGRect expectedFrame = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.pageViewController.view.bounds), CGRectGetHeight(self.pageViewController.view.bounds)); 91 | 92 | XCTAssert(CGRectEqualToRect(finalFrame, expectedFrame)); 93 | } 94 | 95 | - (void)testVerticalPageFrame_02 96 | { 97 | [self.pageLayouter setNavigationType:SCPageLayouterNavigationTypeVertical]; 98 | [self.pageLayouter setInterItemSpacing:-100.0f]; 99 | 100 | CGRect finalFrame = [self.pageLayouter finalFrameForPageAtIndex:1 pageViewController:self.pageViewController]; 101 | CGRect expectedFrame = CGRectMake(0.0f, 102 | CGRectGetHeight(self.pageViewController.view.bounds) + self.pageLayouter.interItemSpacing, 103 | CGRectGetWidth(self.pageViewController.view.bounds), 104 | CGRectGetHeight(self.pageViewController.view.bounds)); 105 | 106 | XCTAssert(CGRectEqualToRect(finalFrame, expectedFrame)); 107 | } 108 | 109 | - (void)testVerticalPageFrame_03 110 | { 111 | [self.pageLayouter setNavigationType:SCPageLayouterNavigationTypeVertical]; 112 | [self.pageLayouter setInterItemSpacing:10.0f]; 113 | 114 | CGRect finalFrame = [self.pageLayouter finalFrameForPageAtIndex:1 pageViewController:self.pageViewController]; 115 | CGRect expectedFrame = CGRectMake(0.0f, 116 | CGRectGetHeight(self.pageViewController.view.bounds) + self.pageLayouter.interItemSpacing, 117 | CGRectGetWidth(self.pageViewController.view.bounds), 118 | CGRectGetHeight(self.pageViewController.view.bounds)); 119 | 120 | XCTAssert(CGRectEqualToRect(finalFrame, expectedFrame)); 121 | } 122 | 123 | - (void)testVerticalPageFrame_04 124 | { 125 | [self.pageLayouter setNavigationType:SCPageLayouterNavigationTypeVertical]; 126 | [self.pageLayouter setInterItemSpacing:123.0f]; 127 | 128 | NSUInteger pageIndex = 123; 129 | 130 | CGRect finalFrame = [self.pageLayouter finalFrameForPageAtIndex:123 pageViewController:self.pageViewController]; 131 | CGRect expectedFrame = CGRectMake(0.0f, 132 | (CGRectGetHeight(self.pageViewController.view.bounds) + self.pageLayouter.interItemSpacing) * pageIndex, 133 | CGRectGetWidth(self.pageViewController.view.bounds), 134 | CGRectGetHeight(self.pageViewController.view.bounds)); 135 | 136 | XCTAssert(CGRectEqualToRect(finalFrame, expectedFrame)); 137 | } 138 | 139 | 140 | 141 | @end 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SCPageViewController 2 | 3 | 4 | SCPageViewController is a container view controller similar to UIPageViewController but which provides more control, is much more customizable and, arguably, has a better overall design. 5 | It supports the following features: 6 | 7 | - Customizable transitions and animations (through layouters and custom easing functions) 8 | - Incremental updates with user defined animations 9 | - Bouncing and realistic physics 10 | - Correct appearance calls, even while interactions are in progres 11 | - Custom layouts and animated layout changes 12 | - Vertical and horizontal layouts 13 | - Pagination 14 | - Content insets 15 | - Completion blocks 16 | - Customizable interaction area and number of touches required 17 | 18 | and more.. 19 | 20 | #### Screenshots 21 | 22 | ![](https://drive.google.com/u/0/uc?id=1rzHLmAsoqfq_lY3gKoJfela769WmyGIk&export=download) 23 | 24 | ## Implementation details 25 | 26 | SCPageViewController is build on top of an UIScrollView subclass ([SCScrollView](https://github.com/stefanceriu/SCScrollView)) which provides it with correct physics, callbacks for building the pagination, navigational constraints and custom transitions. It also can work with user defined interaction areas and minimum/maximum number of touches. It's worth noting that SCScrollView also powers [SCStackViewController](https://github.com/stefanceriu/SCStackViewController) 27 | 28 | SCPageViewController relies on page layouters to know where to place each of the controllers at every point. Page layouters are built on top of a simple protocol with methods for providing the final and intermediate view controller frames, and custom animations for page insertions, deletions, moves and reloads. The demo project contains 4 examples: plain with inter-item spacings, parallax, sliding and cards. 29 | 30 | ## Usage 31 | 32 | - Create a new instance and set its data source and delegate 33 | 34 | ```objc 35 | self.pageViewController = [[SCPageViewController alloc] init]; 36 | [self.pageViewController setDataSource:self]; 37 | [self.pageViewController setDelegate:self]; 38 | ``` 39 | 40 | - SCPageViewController relies on layouters that define how pages are layed out. You can use one of the included ones or create a custom class that implements the SCPageLayouterProtocol. 41 | 42 | ```objc 43 | [self.pageViewController setLayouter:[[SCPageLayouter alloc] init] animated:NO completion:nil]; 44 | ``` 45 | 46 | - Implement the SCPageViewControllerDataSource to define the total number of pages, the view controllers to be used for each of them and which one show be displayed first. 47 | 48 | ```objc 49 | - (NSUInteger)numberOfPagesInPageViewController:(SCPageViewController *)pageViewController; 50 | 51 | - (UIViewController *)pageViewController:(SCPageViewController *)pageViewController viewControllerForPageAtIndex:(NSUInteger)pageIndex; 52 | 53 | - (NSUInteger)initialPageInPageViewController:(SCPageViewController *)pageViewController; 54 | ``` 55 | 56 | - Optionally, modify the following properties to your liking 57 | 58 | ```objc 59 | // Enable/disable pagination 60 | [self.pageViewController setPagingEnabled:NO]; 61 | 62 | // Ignore navigation contraints (bounce between pages) 63 | [self.pageViewController setContinuousNavigationEnabled:YES]; 64 | 65 | // Have the page view controller come to a rest slower 66 | [self.pageViewController.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal]; 67 | 68 | // Disable bouncing 69 | [self.pageViewController.scrollView setBounces:NO]; 70 | 71 | // Customize how many number of touches are required to interact with the pages 72 | [self.pageViewController.scrollView.panGestureRecognizer setMinimumNumberOfTouches:2]; 73 | [self.pageViewController.scrollView setMaximumNumberOfTouches:1]; 74 | 75 | // Allow interaction only in the specified area 76 | //SCScrollViewTouchApprovalArea *touchApprovalArea = [[SCScrollViewTouchApprovalArea alloc] init]; 77 | //[touchApprovalArea setPath:[UIBezierPath bezierPathWithRect:someFrame]]; 78 | //[self.pageViewController.scrollView addTouchApprovalArea:touchApprovalArea]; 79 | 80 | //Use different easing functions for animations and navigation 81 | [self.pageViewController setEasingFunction:[SCEasingFunction easingFunctionWithType:SCEasingFunctionTypeLinear]]; 82 | 83 | // Change the default animation durations 84 | [self.pageViewController setAnimationDuration:1.0f]; 85 | ``` 86 | 87 | #####Incremental updates 88 | SCPageViewController also supports incremental updates and all the animations are customizable through the layouter. 89 | 90 | ```objc 91 | [self.pageViewController insertPagesAtIndexes:(NSIndexSet *)indexes animated:(BOOL)animated completion:^(void)completion]; 92 | 93 | [self.pageViewController deletePagesAtIndexes:(NSIndexSet *)indexes animated:(BOOL)animated completion:^(void)completion] 94 | 95 | [self.pageViewController reloadPagesAtIndexes:(NSIndexSet *)indexes animated:(BOOL)animated completion:^(void)completion] 96 | 97 | [self.pageViewController movePageAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex animated:(BOOL)animated completion:^(void)completion] 98 | ``` 99 | 100 | #####Easing functions 101 | 102 | SCPageViewController can work with custom easing functions defined through the SCEasingFunctionProtocol. It comes bundled with 31 different ones (thanks to AHEasing) and new ones can be created with ease. 103 | 104 | * Ease In Out Back 105 | ![Plain+BackEaseInOut](https://drive.google.com/u/0/uc?id=1DgqHRNjY0GjVViupQlLAPieuOc_EG4Zv&export=download) 106 | 107 | * Ease Out Bounce 108 | ![Plain+BounceEaseOut](https://drive.google.com/u/0/uc?id=1djURb38aDzH0xgs-BrP-FnPW7a5I5UMa&export=download) 109 | 110 | * Ease Out Elastic 111 | ![Plain+ElasticEaseOut](https://drive.google.com/u/0/uc?id=1y4uNGO7DxbwQncCBwxvcCKVTedlBefKS&export=download) 112 | 113 | ##### For more usage examples please have a look at the included demo project (or `pod try SCPageViewController`) 114 | 115 | ## License 116 | SCPageViewController is released under the MIT License (MIT) (see the LICENSE file) 117 | 118 | ## Contact 119 | Any suggestions or improvements are more than welcome and I would also love to know if you are using this component in a published application. 120 | Feel free to contact me at [stefan.ceriu@gmail.com](mailto:stefan.ceriu@gmail.com) or [@stefanceriu](https://twitter.com/stefanceriu). 121 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCRootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCRootViewController.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCRootViewController.h" 10 | #import "SCPageViewController.h" 11 | #import "SCMainViewController.h" 12 | 13 | #import "SCEasingFunction.h" 14 | 15 | #import "SCPageLayouter.h" 16 | #import "SCSlidingPageLayouter.h" 17 | #import "SCParallaxPageLayouter.h" 18 | #import "SCCardsPageLayouter.h" 19 | 20 | #import "UIColor+RandomColors.h" 21 | 22 | static const NSUInteger kDefaultNumberOfPages = 5; 23 | 24 | @interface SCRootViewController () 25 | 26 | @property (nonatomic, strong) SCPageViewController *pageViewController; 27 | 28 | @property (nonatomic, assign) SCEasingFunctionType selectedEasingFunctionType; 29 | @property (nonatomic, strong) NSMutableArray *viewControllers; 30 | 31 | @end 32 | 33 | @implementation SCRootViewController 34 | 35 | - (void)viewDidLoad 36 | { 37 | [super viewDidLoad]; 38 | 39 | self.viewControllers = [NSMutableArray array]; 40 | for(int i=0; i < kDefaultNumberOfPages; i++) { 41 | [self.viewControllers addObject:[NSNull null]]; 42 | } 43 | 44 | self.pageViewController = [[SCPageViewController alloc] init]; 45 | [self.pageViewController setDataSource:self]; 46 | [self.pageViewController setDelegate:self]; 47 | 48 | [self.pageViewController setLayouter:[[SCPageLayouter alloc] init] animated:NO completion:nil]; 49 | [self.pageViewController setEasingFunction:[SCEasingFunction easingFunctionWithType:SCEasingFunctionTypeLinear]]; 50 | 51 | [self addChildViewController:self.pageViewController]; 52 | [self.pageViewController.view setFrame:self.view.bounds]; 53 | [self.view addSubview:self.pageViewController.view]; 54 | [self.pageViewController didMoveToParentViewController:self]; 55 | 56 | [self _updateViewControllerDetails]; 57 | } 58 | 59 | #pragma mark - SCPageViewControllerDataSource 60 | 61 | - (NSUInteger)numberOfPagesInPageViewController:(SCPageViewController *)pageViewController 62 | { 63 | return self.viewControllers.count; 64 | } 65 | 66 | - (UIViewController *)pageViewController:(SCPageViewController *)pageViewController viewControllerForPageAtIndex:(NSUInteger)pageIndex 67 | { 68 | SCMainViewController *viewController = self.viewControllers[pageIndex]; 69 | 70 | if([viewController isEqual:[NSNull null]]) { 71 | viewController = [[SCMainViewController alloc] init]; 72 | [viewController.view setFrame:self.view.bounds]; 73 | [viewController setDelegate:self]; 74 | [viewController.contentView setBackgroundColor:[UIColor randomColor]]; 75 | 76 | [self.viewControllers replaceObjectAtIndex:pageIndex withObject:viewController]; 77 | } 78 | 79 | return viewController; 80 | } 81 | 82 | - (NSUInteger)initialPageInPageViewController:(SCPageViewController *)pageViewController 83 | { 84 | return 4; 85 | } 86 | 87 | #pragma mark - SCPageViewControllerDelegate 88 | 89 | - (void)pageViewController:(SCPageViewController *)pageViewController didNavigateToOffset:(CGPoint)offset 90 | { 91 | [self _updateViewControllerDetails]; 92 | } 93 | 94 | #pragma mark - SCMainViewControllerDelegate 95 | 96 | - (void)mainViewControllerDidChangeLayouterType:(SCMainViewController *)mainViewController 97 | { 98 | static NSDictionary *typeToLayouter; 99 | static dispatch_once_t onceToken; 100 | dispatch_once(&onceToken, ^{ 101 | typeToLayouter = (@{@(SCPageLayouterTypePlain) : [SCPageLayouter class], 102 | @(SCPageLayouterTypeSliding) : [SCSlidingPageLayouter class], 103 | @(SCPageLayouterTypeParallax) : [SCParallaxPageLayouter class], 104 | @(SCPageLayouterTypeCards) : [SCCardsPageLayouter class]}); 105 | }); 106 | 107 | id pageLayouter = [[typeToLayouter[@(mainViewController.layouterType)] alloc] init]; 108 | [self.pageViewController setLayouter:pageLayouter animated:YES completion:nil]; 109 | 110 | [self _updateViewControllerDetails]; 111 | } 112 | 113 | - (void)mainViewControllerDidChangeAnimationType:(SCMainViewController *)mainViewController 114 | { 115 | [self.pageViewController setEasingFunction:[SCEasingFunction easingFunctionWithType:mainViewController.easingFunctionType]]; 116 | self.selectedEasingFunctionType = mainViewController.easingFunctionType; 117 | 118 | [self _updateViewControllerDetails]; 119 | } 120 | 121 | - (void)mainViewControllerDidChangeAnimationDuration:(SCMainViewController *)mainViewController 122 | { 123 | [self.pageViewController setAnimationDuration:mainViewController.duration]; 124 | } 125 | 126 | - (void)mainViewControllerDidRequestNavigationToNextPage:(SCMainViewController *)mainViewController 127 | { 128 | [self.pageViewController navigateToPageAtIndex:MIN(self.pageViewController.numberOfPages, self.pageViewController.currentPage + 1) animated:YES completion:nil]; 129 | } 130 | 131 | - (void)mainViewControllerDidRequestNavigationToPreviousPage:(SCMainViewController *)mainViewController 132 | { 133 | [self.pageViewController navigateToPageAtIndex:MAX(0, self.pageViewController.currentPage - 1) animated:YES completion:nil]; 134 | } 135 | 136 | - (void)mainViewControllerDidRequestPageInsertion:(SCMainViewController *)mainViewController 137 | { 138 | [self _insertPagesAtIndexes:[NSIndexSet indexSetWithIndex:[self.viewControllers indexOfObject:mainViewController]]]; 139 | [self _updateViewControllerDetails]; 140 | } 141 | 142 | - (void)mainViewControllerDidRequestPageDeletion:(SCMainViewController *)mainViewController 143 | { 144 | [self _deletePagesAtIndexes:[NSIndexSet indexSetWithIndex:[self.viewControllers indexOfObject:mainViewController]]]; 145 | [self _updateViewControllerDetails]; 146 | } 147 | 148 | #pragma mark - Private 149 | 150 | - (void)_reloadPagesAtIndexes:(NSIndexSet *)indexes 151 | { 152 | [indexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { 153 | [self.viewControllers replaceObjectAtIndex:idx withObject:[NSNull null]]; 154 | }]; 155 | 156 | [self.pageViewController reloadPagesAtIndexes:indexes animated:YES completion:nil]; 157 | } 158 | 159 | - (void)_insertPagesAtIndexes:(NSIndexSet *)indexes 160 | { 161 | [indexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { 162 | [self.viewControllers insertObject:[NSNull null] atIndex:idx]; 163 | }]; 164 | 165 | [self.pageViewController insertPagesAtIndexes:indexes animated:YES completion:nil]; 166 | } 167 | 168 | - (void)_deletePagesAtIndexes:(NSIndexSet *)indexes 169 | { 170 | [indexes enumerateIndexesWithOptions:NSEnumerationReverse usingBlock:^(NSUInteger idx, BOOL *stop) { 171 | [self.viewControllers removeObjectAtIndex:idx]; 172 | }]; 173 | 174 | [self.pageViewController deletePagesAtIndexes:indexes animated:YES completion:nil]; 175 | } 176 | 177 | - (void)_movePageFromIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex 178 | { 179 | UIViewController *viewController = [self.viewControllers objectAtIndex:fromIndex]; 180 | [self.viewControllers removeObjectAtIndex:fromIndex]; 181 | [self.viewControllers insertObject:viewController atIndex:toIndex]; 182 | 183 | [self.pageViewController movePageAtIndex:fromIndex toIndex:toIndex animated:YES completion:nil]; 184 | } 185 | 186 | - (void)_updateViewControllerDetails 187 | { 188 | [self.viewControllers enumerateObjectsUsingBlock:^(SCMainViewController *controller, NSUInteger index, BOOL *stop) { 189 | 190 | if([controller isEqual:[NSNull null]]) { 191 | return; 192 | } 193 | 194 | [controller.visiblePercentageLabel setText:[NSString stringWithFormat:@"%.2f%%", [self.pageViewController visiblePercentageForViewController:controller]]]; 195 | 196 | [controller.pageNumberLabel setText:[NSString stringWithFormat:@"Page %lu of %lu", (unsigned long)index, (unsigned long)self.pageViewController.numberOfPages]]; 197 | 198 | [controller setEasingFunctionType:self.selectedEasingFunctionType]; 199 | [controller setDuration:self.pageViewController.animationDuration]; 200 | 201 | static NSDictionary *layouterToType; 202 | static dispatch_once_t onceToken; 203 | dispatch_once(&onceToken, ^{ 204 | layouterToType = (@{NSStringFromClass([SCPageLayouter class]) : @(SCPageLayouterTypePlain), 205 | NSStringFromClass([SCSlidingPageLayouter class]) : @(SCPageLayouterTypeSliding), 206 | NSStringFromClass([SCParallaxPageLayouter class]) : @(SCPageLayouterTypeParallax), 207 | NSStringFromClass([SCCardsPageLayouter class]) : @(SCPageLayouterTypeCards)}); 208 | }); 209 | 210 | [controller setLayouterType:(SCPageLayouterType)[layouterToType[NSStringFromClass([self.pageViewController.layouter class])] unsignedIntegerValue]]; 211 | }]; 212 | } 213 | 214 | @end 215 | -------------------------------------------------------------------------------- /SCPageViewController/Layouters/SCPageLayouterProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCPageLayouterProtocol.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCPageViewController.h" 10 | 11 | /** An object adopting the SCPageLayouter protocol is responsible for returning 12 | * the itermediate and final frames for the PageViewControllers's children when called. 13 | * They have access the the actual children so that they can customize the navigation 14 | * effects at each point of the transition. 15 | */ 16 | 17 | typedef NS_ENUM(NSUInteger, SCPageLayouterNavigationType) { 18 | SCPageLayouterNavigationTypeHorizontal, 19 | SCPageLayouterNavigationTypeVertical, 20 | }; 21 | 22 | /** Navigation contraint types that can be used used when continuous navigation is disabled */ 23 | typedef NS_OPTIONS(NSUInteger, SCPageLayouterNavigationContraintType) { 24 | SCPageLayouterNavigationContraintTypeNone = 0, 25 | SCPageLayouterNavigationContraintTypeForward = 1 << 0, /** Scroll view bounces on page bounds only when navigating forward*/ 26 | SCPageLayouterNavigationContraintTypeReverse = 1 << 1 /** Scroll view bounces on page bounds only when navigating backwards*/ 27 | }; 28 | 29 | 30 | /** 31 | * The page layouter protocol specifies the required and optional methods that define 32 | * how pages are laid out on screen and how they are animated while performing 33 | * incremental updates 34 | */ 35 | @protocol SCPageLayouterProtocol 36 | 37 | /** Defines the direction the pages are laid out */ 38 | @property (nonatomic, assign) SCPageLayouterNavigationType navigationType; 39 | 40 | 41 | /** Defines when the page view controller should enforce page bounds while navigating */ 42 | @property (nonatomic, assign) SCPageLayouterNavigationContraintType navigationConstraintType; 43 | 44 | 45 | /** The number of pages to preload and add to the page view controller before the current page */ 46 | @property (nonatomic, assign) NSUInteger numberOfPagesToPreloadBeforeCurrentPage; 47 | 48 | 49 | /** The number of pages to preload and add to the page view controller after the current page */ 50 | @property (nonatomic, assign) NSUInteger numberOfPagesToPreloadAfterCurrentPage; 51 | 52 | 53 | /** Returns the final frame for the given view controller 54 | * 55 | * @param index The index of the view controller in the PageViewController's children array 56 | * @param pageViewController The calling PageViewController 57 | * @return The frame for the viewController's view 58 | */ 59 | - (CGRect)finalFrameForPageAtIndex:(NSUInteger)index 60 | pageViewController:(SCPageViewController *)pageViewController; 61 | 62 | 63 | @optional 64 | 65 | /** The amount of space in between each page 66 | * 67 | * @param pageViewController the calling page view controller 68 | * @return the spacing to be used 69 | */ 70 | - (CGFloat)interItemSpacingForPageViewController:(SCPageViewController *)pageViewController; 71 | 72 | 73 | /** Defines the empty space useds before and after pages 74 | * Based on the navigationType the pageController only uses a pair (top/bottom, 75 | * left/right) 76 | * 77 | * @param pageViewController the calling page view controller 78 | * @return the insets to be used 79 | */ 80 | - (UIEdgeInsets)contentInsetForPageViewController:(SCPageViewController *)pageViewController; 81 | 82 | 83 | /** Returns the intermediate frame for the given view controller and current 84 | * offset 85 | * 86 | * @param index The index of the view controller 87 | * @param contentOffset current offset in the PageViewController's scrollView 88 | * @param pageViewController The calling SCPageViewController 89 | * @return The frame for the viewController's view 90 | */ 91 | - (CGRect)currentFrameForPageAtIndex:(NSUInteger)index 92 | contentOffset:(CGPoint)contentOffset 93 | finalFrame:(CGRect)finalFrame 94 | pageViewController:(SCPageViewController *)pageViewController; 95 | 96 | 97 | /** Defines the z position which should be used when laying out the given view controller 98 | * Defaults to the inverse of the page order 99 | * 100 | * @param index the page index for the given view controller 101 | * @param pageViewController the calling page view controller 102 | * @return the index the view controller we be places at in the view hierarchy 103 | */ 104 | - (NSUInteger)zPositionForPageAtIndex:(NSUInteger)index 105 | pageViewController:(SCPageViewController *)pageViewController; 106 | 107 | 108 | /** Returns the view controller sublayer transformation that should be used 109 | * for the current offset 110 | * 111 | * @param index The index of the view controller in the Stack's children array 112 | * @param pageViewController The calling page view controller 113 | * @return The sublayer transformation to be applied 114 | */ 115 | - (CATransform3D)sublayerTransformForPageAtIndex:(NSUInteger)index 116 | contentOffset:(CGPoint)contentOffset 117 | pageViewController:(SCPageViewController *)pageViewController; 118 | 119 | 120 | /** Method that the pageController calls when its scrollView scrolls 121 | * @param pageViewController The calling PageViewController 122 | * @param offset The current offset in the PageViewController's scrollView 123 | */ 124 | - (void)pageViewController:(SCPageViewController *)pageViewController 125 | didNavigateToOffset:(CGPoint)offset; 126 | 127 | 128 | /** Called by the pageViewController when it receives a reload page animated 129 | * request. 130 | * The completion call must be called after finishing customizations so that 131 | * the pageViewController can continue the layout 132 | * 133 | * @param index The index of the page about to be reloaded 134 | * @param oldViewController The view controller about to be removed 135 | * @param newViewController The view controller that is going to be inserted 136 | * @param pageViewController the calling pageViewController 137 | * @param completion block that lets the pageViewController know that it can 138 | * proceed with the layout 139 | */ 140 | - (void)animatePageReloadAtIndex:(NSUInteger)index 141 | oldViewController:(UIViewController *)oldViewController 142 | newViewController:(UIViewController *)newViewController 143 | pageViewController:(SCPageViewController *)pageViewController 144 | completion:(void(^)(void))completion; 145 | 146 | 147 | /** Called by the pageViewController when it receives an insert page animated 148 | * request. 149 | * The completion call must be called after finishing customizations so that 150 | * the pageViewController can continue the layout 151 | * 152 | * @param index The index where a new page will be inserted 153 | * @param viewController The view controller that is going to be inserted 154 | * @param pageViewController the calling pageViewController 155 | * @param completion block that lets the pageViewController know that it can 156 | * proceed with the layout 157 | */ 158 | - (void)animatePageInsertionAtIndex:(NSUInteger)index 159 | viewController:(UIViewController *)viewController 160 | pageViewController:(SCPageViewController *)pageViewController 161 | completion:(void(^)(void))completion; 162 | 163 | /** Called bue the pageViewController when inserting a new page that 164 | * would affect the current content offset 165 | * 166 | * @param index The index where a new page will be inserted 167 | * @param pageViewController the calling pageViewController 168 | * @return a boolean indicating whether the current offset should be kept 169 | */ 170 | - (BOOL)shouldPreserveOffsetForInsertionAtIndex:(NSUInteger)index 171 | pageViewController:(SCPageViewController *)pageViewController; 172 | 173 | 174 | /** Called by the pageViewController when it receives a delete page animated 175 | * request. 176 | * The completion call must be called after finishing customizations so that 177 | * the pageViewController can continue the layout 178 | * 179 | * @param index The index where a new page will be deleted 180 | * @param viewController The view controller that is going to be deleted 181 | * @param pageViewController the calling pageViewController 182 | * @param completion block that lets the pageViewController know that it can 183 | * proceed with the layout 184 | */ 185 | - (void)animatePageDeletionAtIndex:(NSUInteger)index 186 | viewController:(UIViewController *)viewController 187 | pageViewController:(SCPageViewController *)pageViewController 188 | completion:(void(^)(void))completion; 189 | 190 | 191 | /** Called by the pageViewController when it receives an move page animated 192 | * request. 193 | * The completion call must be called after finishing customizations so that 194 | * the pageViewController can continue the layout 195 | * 196 | * @param fromIndex The orinal index of the page 197 | * @param toIndex The final index of the page after updates 198 | * @param viewController The view controller that is going to be moved 199 | * @param pageViewController the calling pageViewController 200 | * @param completion block that lets the pageViewController know that it can 201 | * proceed with the layout 202 | */ 203 | - (void)animatePageMoveFromIndex:(NSUInteger)fromIndex 204 | toIndex:(NSUInteger)toIndex 205 | viewController:(UIViewController *)viewController 206 | pageViewController:(SCPageViewController *)pageViewController 207 | completion:(void(^)(void))completion; 208 | 209 | @end 210 | -------------------------------------------------------------------------------- /SCPageViewController/SCPageViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCPageViewController.h 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @class SCScrollView; 12 | 13 | @protocol SCPageViewControllerDataSource; 14 | @protocol SCPageViewControllerDelegate; 15 | @protocol SCPageLayouterProtocol; 16 | 17 | @protocol SCEasingFunctionProtocol; 18 | 19 | /** SCPageViewController is a container view controller which allows 20 | * you to paginate other view controllers and build custom transitions 21 | * between them while providing correct physics and appearance calls. 22 | */ 23 | @interface SCPageViewController : UIViewController 24 | 25 | /** Sets the layouter that the pageController should use 26 | * @param layouter the layouter that should be used 27 | * @param animated whether the change should be animated 28 | * @param completion the block to be called when the transition is over 29 | */ 30 | - (void)setLayouter:(id)layouter 31 | animated:(BOOL)animated 32 | completion:(void(^)(void))completion; 33 | 34 | 35 | /** Sets the layouter and also focuses on the given index 36 | * @param layouter the layouter that should be used 37 | * @param pageIndex the page index to focus on 38 | * @param animated whether the change should be animated 39 | * @param completion the block to be called when the transition is over 40 | */ 41 | - (void)setLayouter:(id)layouter 42 | andFocusOnIndex:(NSUInteger)pageIndex 43 | animated:(BOOL)animated 44 | completion:(void(^)(void))completion; 45 | 46 | 47 | /** Reloads and re-lays out all the pages */ 48 | - (void)reloadData; 49 | 50 | 51 | /** Reloads and re-layouts the pages at the given indexes 52 | * @param indexes the indexes of the pages that should be reloaded 53 | * @param animated whether the reload should be animated 54 | * @param completion the block to be called when the pages have been reloaded 55 | */ 56 | - (void)reloadPagesAtIndexes:(NSIndexSet *)indexes animated:(BOOL)animated completion:(void(^)(void))completion; 57 | 58 | 59 | /** Inserts new pages at the given indexes 60 | * @param indexes the indexes where new pages should be inserted 61 | * @param animated whether the insertions should be animated 62 | * @param completion the block to be called when the pages have been inserted 63 | */ 64 | - (void)insertPagesAtIndexes:(NSIndexSet *)indexes animated:(BOOL)animated completion:(void(^)(void))completion; 65 | 66 | 67 | /** Removes the pages from the given indexes 68 | * @param indexes the indexes from where pages should be deleted 69 | * @param animated whether the deletions should be animated 70 | * @param completion the block to be called when the pages have been deleted 71 | */ 72 | - (void)deletePagesAtIndexes:(NSIndexSet *)indexes animated:(BOOL)animated completion:(void(^)(void))completion; 73 | 74 | 75 | /** Moves a page from one index to another 76 | * @param fromIndex the initial page index 77 | * @param toIndex the final page index 78 | * @param animated whether the move should be animated 79 | * @param completion the block to be called when the page has been moved 80 | */ 81 | - (void)movePageAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex animated:(BOOL)animated completion:(void(^)(void))completion; 82 | 83 | 84 | /** Navigates to the given page index 85 | * @param pageIndex The page index to navigate to 86 | * @param animated Whether the transition will be animated 87 | * @param completion the block to be called when the navigation finished 88 | */ 89 | - (void)navigateToPageAtIndex:(NSUInteger)pageIndex 90 | animated:(BOOL)animated 91 | completion:(void(^)(void))completion; 92 | 93 | 94 | /** 95 | * @param viewController The view controller for which to fetch the 96 | * visible percentage 97 | * @return Float value representing the visible percentage 98 | * 99 | * @discussion A view controller is visible when any part of it is visible (within the 100 | * PageController's scrollView bounds and not covered by any other view) 101 | * Ranges from 0.0f to 1.0f 102 | */ 103 | - (CGFloat)visiblePercentageForViewController:(UIViewController *)viewController; 104 | 105 | 106 | /** Retrieves the view controller for the given page, if loaded, nil otherwise 107 | * @param pageIndex The page index you want to retrieve the view controller for 108 | * @return the view controller for the given page index if already loaded, nil otherwise 109 | */ 110 | - (UIViewController *)viewControllerForPageAtIndex:(NSUInteger)pageIndex; 111 | 112 | 113 | /** Retrieves the page index for the given view controller 114 | * @param viewController The viewController for which to retrieve the page index 115 | * @return The page index for the given view controller or NSNotFound 116 | */ 117 | - (NSUInteger)pageIndexForViewController:(UIViewController *)viewController; 118 | 119 | 120 | /** Currently used layouter */ 121 | @property (nonatomic, readonly) id layouter; 122 | 123 | 124 | /** The page view controller's data source */ 125 | @property (nonatomic, weak) id dataSource; 126 | 127 | 128 | /** The page view controller's delegate */ 129 | @property (nonatomic, weak) id delegate; 130 | 131 | 132 | /** The internal scroll view */ 133 | @property (nonatomic, strong, readonly) SCScrollView *scrollView; 134 | 135 | 136 | /** The current page in the page view controller */ 137 | @property (nonatomic, readonly) NSUInteger currentPage; 138 | 139 | 140 | /** The total number of pages the page view controllers holds at any given time */ 141 | @property (nonatomic, readonly) NSUInteger numberOfPages; 142 | 143 | 144 | /** Whether the page controller's view is visible or not */ 145 | @property (nonatomic, readonly) BOOL visible; 146 | 147 | 148 | /** An array of currently loaded view controllers in the page view controller */ 149 | @property (nonatomic, readonly) NSArray *loadedViewControllers; 150 | 151 | 152 | /** An array of currently visible view controllers in the page view controller */ 153 | @property (nonatomic, readonly) NSArray *visibleViewControllers; 154 | 155 | 156 | /** A Boolean value that determines whether paging is enabled for the pageController's 157 | * scrollView. 158 | * 159 | * Default value is set to true 160 | */ 161 | @property (nonatomic, assign) BOOL pagingEnabled; 162 | 163 | 164 | /** A Boolean value that determines whether the user can freely scroll between 165 | * pages 166 | * 167 | * When set to true the PageController's scrollView bounces on every page. Navigating 168 | * through more than 1 page will require multiple swipes. 169 | * 170 | * Default value is set to false 171 | */ 172 | @property (nonatomic, assign) BOOL continuousNavigationEnabled; 173 | 174 | 175 | /** Tells the pageViewController to layout pages only when the scroll rests 176 | * @discussion Setting this to true will prevent the page view controller from using 177 | * the layouter to set current page frames while navigating 178 | */ 179 | @property (nonatomic, assign) BOOL shouldLayoutPagesOnRest; 180 | 181 | 182 | /** Timing function used when navigating beteen pages 183 | * 184 | * Default value is set to SCEasingFunctionTypeSineEaseInOut 185 | */ 186 | @property (nonatomic, strong) id easingFunction; 187 | 188 | 189 | /** Animation duration used when navigating beteen pages 190 | * 191 | * Default value is set to 0.25f 192 | */ 193 | @property (nonatomic, assign) NSTimeInterval animationDuration; 194 | 195 | 196 | @end 197 | 198 | 199 | /** The page view controller's dataSource protocol */ 200 | @protocol SCPageViewControllerDataSource 201 | 202 | /** 203 | * @param pageViewController The calling PageViewController 204 | * @return Number of items in the page view controller 205 | */ 206 | - (NSUInteger)numberOfPagesInPageViewController:(SCPageViewController *)pageViewController; 207 | 208 | 209 | /** 210 | * @param pageViewController The calling PageViewController 211 | * @param pageIndex The index for which to retrieve the view controller 212 | * @return The view controller to be uses for the given index 213 | */ 214 | - (UIViewController *)pageViewController:(SCPageViewController *)pageViewController viewControllerForPageAtIndex:(NSUInteger)pageIndex; 215 | 216 | /** 217 | * @param pageViewController The calling PageViewController 218 | * @return The initial page that should be loaded, otherwise the first is chosen. 219 | */ 220 | @optional 221 | - (NSUInteger)initialPageInPageViewController:(SCPageViewController *)pageViewController; 222 | 223 | @end 224 | 225 | 226 | /** The page view controller's delegate protocol */ 227 | @protocol SCPageViewControllerDelegate 228 | 229 | @optional 230 | 231 | /** Delegate method that the PageViewController calls when a view controller becomes visible 232 | * 233 | * @param pageViewController The calling PageViewController 234 | * @param controller The view controller that became visible 235 | * @param index The view controller index 236 | * 237 | * A view controller is visible when any part of it is visible (within the 238 | * internal scrollView's bounds and not covered by any other view) 239 | */ 240 | - (void)pageViewController:(SCPageViewController *)pageViewController 241 | didShowViewController:(UIViewController *)controller 242 | atIndex:(NSUInteger)index; 243 | 244 | 245 | /** Delegate method that the pageController calls when a view controller is hidden 246 | * @param pageViewController The calling PageViewController 247 | * @param controller The view controller that was hidden 248 | * @param index The position where the view controller resides 249 | * 250 | * A view controller is hidden when it view's frame rests outside the pageController's 251 | * scrollView bounds or when it is fully overlapped by other views 252 | */ 253 | - (void)pageViewController:(SCPageViewController *)pageViewController 254 | didHideViewController:(UIViewController *)controller 255 | atIndex:(NSUInteger)index; 256 | 257 | 258 | /** Delegate method that the pageController calls when its scrollView scrolls 259 | * @param pageViewController The calling PageViewController 260 | * @param offset The current offset in the PageViewController's scrollView 261 | */ 262 | - (void)pageViewController:(SCPageViewController *)pageViewController 263 | didNavigateToOffset:(CGPoint)offset; 264 | 265 | 266 | /** Delegate method that the pageController calls when its scrollView rests 267 | * on a page 268 | * @param pageViewController The calling PageViewController 269 | * @param pageIndex The index of the page 270 | */ 271 | - (void)pageViewController:(SCPageViewController *)pageViewController 272 | didNavigateToPageAtIndex:(NSUInteger)pageIndex; 273 | 274 | @end 275 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCMainViewController.xib: -------------------------------------------------------------------------------- 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 | 38 | 51 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 85 | 97 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /Demo/ObjCDemo/SCMainViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCMainViewController.m 3 | // SCPageViewController 4 | // 5 | // Created by Stefan Ceriu on 15/02/2014. 6 | // Copyright (c) 2014 Stefan Ceriu. All rights reserved. 7 | // 8 | 9 | #import "SCMainViewController.h" 10 | 11 | typedef NS_ENUM(NSUInteger, SCPickerViewComponentType) { 12 | SCPickerViewComponentTypeLayouter, 13 | SCPickerViewComponentTypeEasingFunction, 14 | SCPickerViewComponentTypeAnimationDuration 15 | }; 16 | 17 | @interface SCMainViewController () 18 | 19 | @property (nonatomic, weak) IBOutlet UIView *contentView; 20 | 21 | @property (nonatomic, weak) IBOutlet UILabel *pageNumberLabel; 22 | @property (nonatomic, weak) IBOutlet UILabel *visiblePercentageLabel; 23 | 24 | @property (nonatomic, weak) IBOutlet UIPickerView *pickerView; 25 | 26 | @end 27 | 28 | @implementation SCMainViewController 29 | 30 | - (IBAction)onPreviousButtonTap:(id)sender 31 | { 32 | if([self.delegate respondsToSelector:@selector(mainViewControllerDidRequestNavigationToPreviousPage:)]) { 33 | [self.delegate mainViewControllerDidRequestNavigationToPreviousPage:self]; 34 | } 35 | } 36 | 37 | - (IBAction)onNextButtonTap:(id)sender 38 | { 39 | if([self.delegate respondsToSelector:@selector(mainViewControllerDidRequestNavigationToNextPage:)]) { 40 | [self.delegate mainViewControllerDidRequestNavigationToNextPage:self]; 41 | } 42 | } 43 | 44 | - (IBAction)onInsertButtonTap:(id)sender 45 | { 46 | if([self.delegate respondsToSelector:@selector(mainViewControllerDidRequestPageInsertion:)]) { 47 | [self.delegate mainViewControllerDidRequestPageInsertion:self]; 48 | } 49 | } 50 | 51 | - (IBAction)onDeleteButtonTap:(id)sender 52 | { 53 | if([self.delegate respondsToSelector:@selector(mainViewControllerDidRequestPageDeletion:)]) { 54 | [self.delegate mainViewControllerDidRequestPageDeletion:self]; 55 | } 56 | } 57 | 58 | #pragma mark - UIPickerViewDataSource 59 | 60 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 61 | { 62 | return SCPickerViewComponentTypeAnimationDuration + 1; 63 | } 64 | 65 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 66 | { 67 | switch ((SCPickerViewComponentType)component) { 68 | case SCPickerViewComponentTypeLayouter: 69 | return SCPageLayouterTypeCount; 70 | case SCPickerViewComponentTypeEasingFunction: 71 | return SCEasingFunctionTypeBounceEaseInOut + 1; 72 | case SCPickerViewComponentTypeAnimationDuration: 73 | return 40; 74 | } 75 | } 76 | 77 | - (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component 78 | { 79 | UIFont *font = [UIFont fontWithName:@"Menlo" size:18.0f]; 80 | UIColor *color = [UIColor colorWithWhite:1.0f alpha:1.0f]; 81 | 82 | switch ((SCPickerViewComponentType)component) { 83 | case SCPickerViewComponentTypeLayouter: { 84 | static NSDictionary *typeToString; 85 | static dispatch_once_t onceToken; 86 | dispatch_once(&onceToken, ^{ 87 | typeToString = (@{@(SCPageLayouterTypePlain) : @"Plain", 88 | @(SCPageLayouterTypeSliding) : @"Sliding", 89 | @(SCPageLayouterTypeParallax) : @"Parallax", 90 | @(SCPageLayouterTypeCards) : @"Cards"}); 91 | }); 92 | 93 | return [[NSAttributedString alloc] initWithString:typeToString[@(row)] 94 | attributes:@{NSFontAttributeName: font, NSForegroundColorAttributeName : color}]; 95 | } 96 | case SCPickerViewComponentTypeEasingFunction: 97 | { 98 | static NSDictionary *typeToString; 99 | static dispatch_once_t onceToken; 100 | dispatch_once(&onceToken, ^{ 101 | typeToString = (@{@(SCEasingFunctionTypeLinear) : @"Linear", 102 | 103 | @(SCEasingFunctionTypeQuadraticEaseIn) : @"Quadratic Ease In", 104 | @(SCEasingFunctionTypeQuadraticEaseOut) : @"Quadratic Ease Out", 105 | @(SCEasingFunctionTypeQuadraticEaseInOut) : @"Quadratic Ease In Out", 106 | 107 | @(SCEasingFunctionTypeCubicEaseIn) : @"Cubic Ease In", 108 | @(SCEasingFunctionTypeCubicEaseOut) : @"Cubic Ease Out", 109 | @(SCEasingFunctionTypeCubicEaseInOut) : @"Cubic Ease In Out", 110 | 111 | @(SCEasingFunctionTypeQuarticEaseIn) : @"Quartic Ease In", 112 | @(SCEasingFunctionTypeQuarticEaseOut) : @"Quartic Ease Out", 113 | @(SCEasingFunctionTypeQuarticEaseInOut) : @"Quartic Ease In Out", 114 | 115 | @(SCEasingFunctionTypeQuinticEaseIn) : @"Quintic Ease In", 116 | @(SCEasingFunctionTypeQuinticEaseOut) : @"Quintic Ease Out", 117 | @(SCEasingFunctionTypeQuinticEaseInOut) : @"Quintic Ease In Out", 118 | 119 | @(SCEasingFunctionTypeSineEaseIn) : @"Sine Ease In", 120 | @(SCEasingFunctionTypeSineEaseOut) : @"Sine Ease Out", 121 | @(SCEasingFunctionTypeSineEaseInOut) : @"Sine Ease In Out", 122 | 123 | @(SCEasingFunctionTypeCircularEaseIn) : @"Circular Ease In", 124 | @(SCEasingFunctionTypeCircularEaseOut) : @"Circular Ease Out", 125 | @(SCEasingFunctionTypeCircularEaseInOut) : @"Circular Ease In Out", 126 | 127 | @(SCEasingFunctionTypeExponentialEaseIn) : @"Exponential Ease In", 128 | @(SCEasingFunctionTypeExponentialEaseOut) : @"Exponential Ease Out", 129 | @(SCEasingFunctionTypeExponentialEaseInOut) : @"Exponential Ease In Out", 130 | 131 | @(SCEasingFunctionTypeElasticEaseIn) : @"Elastic Ease In", 132 | @(SCEasingFunctionTypeElasticEaseOut) : @"Elastic Ease Out", 133 | @(SCEasingFunctionTypeElasticEaseInOut) : @"Elastic Ease In Out", 134 | 135 | @(SCEasingFunctionTypeBackEaseIn) : @"Back Ease In", 136 | @(SCEasingFunctionTypeBackEaseOut) : @"Back Ease Out", 137 | @(SCEasingFunctionTypeBackEaseInOut) : @"Back Ease In Out", 138 | 139 | @(SCEasingFunctionTypeBounceEaseIn) : @"Bounce Ease In", 140 | @(SCEasingFunctionTypeBounceEaseOut) : @"Bounce Ease Out", 141 | @(SCEasingFunctionTypeBounceEaseInOut) : @"Bounce Ease In Out"}); 142 | }); 143 | 144 | return [[NSAttributedString alloc] initWithString:typeToString[@(row)] 145 | attributes:@{NSFontAttributeName: font, NSForegroundColorAttributeName : color}]; 146 | } 147 | case SCPickerViewComponentTypeAnimationDuration: 148 | { 149 | return [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%.2f", [self _rowToDuration:row]] 150 | attributes:@{NSFontAttributeName: font, NSForegroundColorAttributeName : color}]; 151 | } 152 | } 153 | } 154 | 155 | #pragma mark - UIPickerViewDelegate 156 | 157 | - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 158 | { 159 | switch ((SCPickerViewComponentType)component) { 160 | case SCPickerViewComponentTypeLayouter: 161 | { 162 | self.layouterType = (SCPageLayouterType)row; 163 | 164 | if([self.delegate respondsToSelector:@selector(mainViewControllerDidChangeLayouterType:)]) { 165 | [self.delegate mainViewControllerDidChangeLayouterType:self]; 166 | } 167 | break; 168 | } 169 | case SCPickerViewComponentTypeEasingFunction: 170 | { 171 | self.easingFunctionType = (SCEasingFunctionType)row; 172 | 173 | if([self.delegate respondsToSelector:@selector(mainViewControllerDidChangeAnimationType:)]) { 174 | [self.delegate mainViewControllerDidChangeAnimationType:self]; 175 | } 176 | break; 177 | } 178 | case SCPickerViewComponentTypeAnimationDuration: 179 | { 180 | self.duration = [self _rowToDuration:row]; 181 | 182 | if([self.delegate respondsToSelector:@selector(mainViewControllerDidChangeAnimationDuration:)]) { 183 | [self.delegate mainViewControllerDidChangeAnimationDuration:self]; 184 | } 185 | break; 186 | } 187 | } 188 | } 189 | 190 | - (NSTimeInterval)_rowToDuration:(NSUInteger)row 191 | { 192 | return 0.25f * (row + 1); 193 | } 194 | 195 | - (NSUInteger)_durationToRow:(NSTimeInterval)duration 196 | { 197 | return duration/0.25f - 1; 198 | } 199 | 200 | #pragma mark - Setters 201 | 202 | - (SCPageLayouterType)layouterType 203 | { 204 | return (SCPageLayouterType)[self.pickerView selectedRowInComponent:SCPickerViewComponentTypeLayouter]; 205 | } 206 | 207 | - (void)setLayouterType:(SCPageLayouterType)layouterType 208 | { 209 | [self.pickerView selectRow:layouterType inComponent:SCPickerViewComponentTypeLayouter animated:NO]; 210 | } 211 | 212 | - (SCEasingFunctionType)easingFunctionType 213 | { 214 | return (SCEasingFunctionType)[self.pickerView selectedRowInComponent:SCPickerViewComponentTypeEasingFunction]; 215 | } 216 | 217 | - (void)setEasingFunctionType:(SCEasingFunctionType)easingFunctionType 218 | { 219 | [self.pickerView selectRow:easingFunctionType inComponent:SCPickerViewComponentTypeEasingFunction animated:NO]; 220 | } 221 | 222 | - (NSTimeInterval)duration 223 | { 224 | return [self _rowToDuration:[self.pickerView selectedRowInComponent:SCPickerViewComponentTypeAnimationDuration]]; 225 | } 226 | 227 | - (void)setDuration:(NSTimeInterval)duration 228 | { 229 | [self.pickerView selectRow:[self _durationToRow:duration] inComponent:SCPickerViewComponentTypeAnimationDuration animated:NO]; 230 | } 231 | 232 | @end 233 | -------------------------------------------------------------------------------- /Demo/SCPageViewController.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 180120F71BCE303E001069CC /* SCPageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EE1BCE3001001069CC /* SCPageViewController.m */; }; 11 | 180120F81BCE3041001069CC /* SCPageViewControllerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120F01BCE3001001069CC /* SCPageViewControllerView.m */; }; 12 | 180120F91BCE3042001069CC /* SCPageViewControllerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120F01BCE3001001069CC /* SCPageViewControllerView.m */; }; 13 | 180120FA1BCE3045001069CC /* SCPageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EE1BCE3001001069CC /* SCPageViewController.m */; }; 14 | 180120FB1BCE304E001069CC /* SCCardsPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120E51BCE3001001069CC /* SCCardsPageLayouter.m */; }; 15 | 180120FC1BCE304E001069CC /* SCPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120E71BCE3001001069CC /* SCPageLayouter.m */; }; 16 | 180120FD1BCE304E001069CC /* SCParallaxPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EA1BCE3001001069CC /* SCParallaxPageLayouter.m */; }; 17 | 180120FE1BCE304E001069CC /* SCSlidingPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EC1BCE3001001069CC /* SCSlidingPageLayouter.m */; }; 18 | 180120FF1BCE304F001069CC /* SCCardsPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120E51BCE3001001069CC /* SCCardsPageLayouter.m */; }; 19 | 180121001BCE304F001069CC /* SCPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120E71BCE3001001069CC /* SCPageLayouter.m */; }; 20 | 180121011BCE304F001069CC /* SCParallaxPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EA1BCE3001001069CC /* SCParallaxPageLayouter.m */; }; 21 | 180121021BCE304F001069CC /* SCSlidingPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EC1BCE3001001069CC /* SCSlidingPageLayouter.m */; }; 22 | 181957BC1B3743B600474C45 /* SCPageLayouterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 181957B81B3743B600474C45 /* SCPageLayouterTests.m */; }; 23 | 181957BD1B3743B600474C45 /* SCPageViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 181957B91B3743B600474C45 /* SCPageViewControllerTests.m */; }; 24 | 181FFE941C14474500DA2369 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181FFE921C14474500DA2369 /* MainViewController.swift */; }; 25 | 181FFE951C14474500DA2369 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 181FFE931C14474500DA2369 /* MainViewController.xib */; }; 26 | 18623FFE18B0063D00FFE998 /* colorful_umbrellas.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 18623FFD18B0063D00FFE998 /* colorful_umbrellas.jpg */; }; 27 | 187E412718A968E0003D8C70 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 187E412618A968E0003D8C70 /* Foundation.framework */; }; 28 | 187E412918A968E0003D8C70 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 187E412818A968E0003D8C70 /* CoreGraphics.framework */; }; 29 | 187E412B18A968E0003D8C70 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 187E412A18A968E0003D8C70 /* UIKit.framework */; }; 30 | 187E413318A968E0003D8C70 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 187E413218A968E0003D8C70 /* main.m */; }; 31 | 187E413718A968E0003D8C70 /* SCAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 187E413618A968E0003D8C70 /* SCAppDelegate.m */; }; 32 | 187E41C618A96A4E003D8C70 /* UIColor+RandomColors.m in Sources */ = {isa = PBXBuildFile; fileRef = 187E41BB18A96A4E003D8C70 /* UIColor+RandomColors.m */; }; 33 | 187E41C718A96A4E003D8C70 /* UIView+Shadows.m in Sources */ = {isa = PBXBuildFile; fileRef = 187E41BD18A96A4E003D8C70 /* UIView+Shadows.m */; }; 34 | 187E41C818A96A4E003D8C70 /* SCMainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 187E41BF18A96A4E003D8C70 /* SCMainViewController.m */; }; 35 | 187E41C918A96A4E003D8C70 /* SCMainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 187E41C018A96A4E003D8C70 /* SCMainViewController.xib */; }; 36 | 187E41CC18A96A4E003D8C70 /* SCRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 187E41C518A96A4E003D8C70 /* SCRootViewController.m */; }; 37 | 187E41CE18A96D2B003D8C70 /* SCRootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 187E41CD18A96D2B003D8C70 /* SCRootViewController.xib */; }; 38 | 18AB9F071BCE2C460049BF9F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18AB9F061BCE2C460049BF9F /* AppDelegate.swift */; }; 39 | 18AB9F1A1BCE2CFA0049BF9F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 18AB9F181BCE2CFA0049BF9F /* LaunchScreen.storyboard */; }; 40 | 18E1DC371B39409F00361240 /* Launch Screen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18E1DC361B39409F00361240 /* Launch Screen.xib */; }; 41 | 18FA31941BCE318800134E86 /* SCCardsPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120E51BCE3001001069CC /* SCCardsPageLayouter.m */; }; 42 | 18FA31951BCE318800134E86 /* SCPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120E71BCE3001001069CC /* SCPageLayouter.m */; }; 43 | 18FA31961BCE318800134E86 /* SCParallaxPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EA1BCE3001001069CC /* SCParallaxPageLayouter.m */; }; 44 | 18FA31971BCE318800134E86 /* SCSlidingPageLayouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EC1BCE3001001069CC /* SCSlidingPageLayouter.m */; }; 45 | 18FA31981BCE318800134E86 /* SCPageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120EE1BCE3001001069CC /* SCPageViewController.m */; }; 46 | 18FA31991BCE318800134E86 /* SCPageViewControllerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 180120F01BCE3001001069CC /* SCPageViewControllerView.m */; }; 47 | 18FA319B1BCE34C500134E86 /* RootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18FA319A1BCE34C500134E86 /* RootViewController.swift */; }; 48 | 4DA3E93AA33E789F6522B06D /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5665E239FB8E5066CF4D7ADA /* libPods-Tests.a */; }; 49 | 848CBCAEC9D6E2E9BEBF8766 /* libPods-ObjCDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 91696FFA725B1AFF96353D9A /* libPods-ObjCDemo.a */; }; 50 | A66C3BD8B4B3A8C21A75CE61 /* libPods-SwiftDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9CAE5D0D4CFCB88876D3233 /* libPods-SwiftDemo.a */; }; 51 | /* End PBXBuildFile section */ 52 | 53 | /* Begin PBXContainerItemProxy section */ 54 | 181957AB1B37432800474C45 /* PBXContainerItemProxy */ = { 55 | isa = PBXContainerItemProxy; 56 | containerPortal = 187E411B18A968E0003D8C70 /* Project object */; 57 | proxyType = 1; 58 | remoteGlobalIDString = 187E412218A968E0003D8C70; 59 | remoteInfo = SCPageViewController; 60 | }; 61 | /* End PBXContainerItemProxy section */ 62 | 63 | /* Begin PBXFileReference section */ 64 | 09819ACCCE4DE4FCEDC4C587 /* Pods-SwiftDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo.release.xcconfig"; sourceTree = ""; }; 65 | 178E2EF528419ADD8E0C7C0F /* Pods-SwiftDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo.debug.xcconfig"; sourceTree = ""; }; 66 | 180120E41BCE3001001069CC /* SCCardsPageLayouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCCardsPageLayouter.h; sourceTree = ""; }; 67 | 180120E51BCE3001001069CC /* SCCardsPageLayouter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCCardsPageLayouter.m; sourceTree = ""; }; 68 | 180120E61BCE3001001069CC /* SCPageLayouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPageLayouter.h; sourceTree = ""; }; 69 | 180120E71BCE3001001069CC /* SCPageLayouter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPageLayouter.m; sourceTree = ""; }; 70 | 180120E81BCE3001001069CC /* SCPageLayouterProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPageLayouterProtocol.h; sourceTree = ""; }; 71 | 180120E91BCE3001001069CC /* SCParallaxPageLayouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCParallaxPageLayouter.h; sourceTree = ""; }; 72 | 180120EA1BCE3001001069CC /* SCParallaxPageLayouter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCParallaxPageLayouter.m; sourceTree = ""; }; 73 | 180120EB1BCE3001001069CC /* SCSlidingPageLayouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCSlidingPageLayouter.h; sourceTree = ""; }; 74 | 180120EC1BCE3001001069CC /* SCSlidingPageLayouter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCSlidingPageLayouter.m; sourceTree = ""; }; 75 | 180120ED1BCE3001001069CC /* SCPageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPageViewController.h; sourceTree = ""; }; 76 | 180120EE1BCE3001001069CC /* SCPageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPageViewController.m; sourceTree = ""; }; 77 | 180120EF1BCE3001001069CC /* SCPageViewControllerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCPageViewControllerView.h; sourceTree = ""; }; 78 | 180120F01BCE3001001069CC /* SCPageViewControllerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPageViewControllerView.m; sourceTree = ""; }; 79 | 181957A51B37432800474C45 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | 181957A81B37432800474C45 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 81 | 181957B81B3743B600474C45 /* SCPageLayouterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPageLayouterTests.m; sourceTree = ""; }; 82 | 181957B91B3743B600474C45 /* SCPageViewControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCPageViewControllerTests.m; sourceTree = ""; }; 83 | 181FFE921C14474500DA2369 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 84 | 181FFE931C14474500DA2369 /* MainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = ""; }; 85 | 18623FFD18B0063D00FFE998 /* colorful_umbrellas.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = colorful_umbrellas.jpg; sourceTree = ""; }; 86 | 187E412318A968E0003D8C70 /* ObjCDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ObjCDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 87 | 187E412618A968E0003D8C70 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 88 | 187E412818A968E0003D8C70 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 89 | 187E412A18A968E0003D8C70 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 90 | 187E412E18A968E0003D8C70 /* SCPageViewController-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SCPageViewController-Info.plist"; sourceTree = ""; }; 91 | 187E413218A968E0003D8C70 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 92 | 187E413518A968E0003D8C70 /* SCAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCAppDelegate.h; sourceTree = ""; }; 93 | 187E413618A968E0003D8C70 /* SCAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SCAppDelegate.m; sourceTree = ""; }; 94 | 187E414518A968E0003D8C70 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 95 | 187E41BA18A96A4E003D8C70 /* UIColor+RandomColors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+RandomColors.h"; sourceTree = ""; }; 96 | 187E41BB18A96A4E003D8C70 /* UIColor+RandomColors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+RandomColors.m"; sourceTree = ""; }; 97 | 187E41BC18A96A4E003D8C70 /* UIView+Shadows.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Shadows.h"; sourceTree = ""; }; 98 | 187E41BD18A96A4E003D8C70 /* UIView+Shadows.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Shadows.m"; sourceTree = ""; }; 99 | 187E41BE18A96A4E003D8C70 /* SCMainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCMainViewController.h; sourceTree = ""; }; 100 | 187E41BF18A96A4E003D8C70 /* SCMainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCMainViewController.m; sourceTree = ""; }; 101 | 187E41C018A96A4E003D8C70 /* SCMainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SCMainViewController.xib; sourceTree = ""; }; 102 | 187E41C418A96A4E003D8C70 /* SCRootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCRootViewController.h; sourceTree = ""; }; 103 | 187E41C518A96A4E003D8C70 /* SCRootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SCRootViewController.m; sourceTree = ""; }; 104 | 187E41CD18A96D2B003D8C70 /* SCRootViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SCRootViewController.xib; sourceTree = ""; }; 105 | 18AB9F041BCE2C450049BF9F /* SwiftDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 106 | 18AB9F061BCE2C460049BF9F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 107 | 18AB9F171BCE2CFA0049BF9F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 108 | 18AB9F181BCE2CFA0049BF9F /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 109 | 18AB9F1E1BCE2F0B0049BF9F /* SwiftDemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SwiftDemo-Bridging-Header.h"; sourceTree = ""; }; 110 | 18E1DC361B39409F00361240 /* Launch Screen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "Launch Screen.xib"; sourceTree = ""; }; 111 | 18FA319A1BCE34C500134E86 /* RootViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootViewController.swift; sourceTree = ""; }; 112 | 2A05B8BF4CD709715791CFDE /* Pods-ObjCDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ObjCDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-ObjCDemo/Pods-ObjCDemo.release.xcconfig"; sourceTree = ""; }; 113 | 52A57530EE2FD7D1E3346871 /* Pods-ObjCDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ObjCDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ObjCDemo/Pods-ObjCDemo.debug.xcconfig"; sourceTree = ""; }; 114 | 5665E239FB8E5066CF4D7ADA /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 115 | 91696FFA725B1AFF96353D9A /* libPods-ObjCDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ObjCDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 116 | C9CAE5D0D4CFCB88876D3233 /* libPods-SwiftDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SwiftDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 117 | D16B58900219A06FC8FB8E02 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; 118 | F297DB8685EE6265766C484F /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = ""; }; 119 | /* End PBXFileReference section */ 120 | 121 | /* Begin PBXFrameworksBuildPhase section */ 122 | 181957A21B37432800474C45 /* Frameworks */ = { 123 | isa = PBXFrameworksBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | 4DA3E93AA33E789F6522B06D /* libPods-Tests.a in Frameworks */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | 187E412018A968E0003D8C70 /* Frameworks */ = { 131 | isa = PBXFrameworksBuildPhase; 132 | buildActionMask = 2147483647; 133 | files = ( 134 | 187E412918A968E0003D8C70 /* CoreGraphics.framework in Frameworks */, 135 | 187E412B18A968E0003D8C70 /* UIKit.framework in Frameworks */, 136 | 187E412718A968E0003D8C70 /* Foundation.framework in Frameworks */, 137 | 848CBCAEC9D6E2E9BEBF8766 /* libPods-ObjCDemo.a in Frameworks */, 138 | ); 139 | runOnlyForDeploymentPostprocessing = 0; 140 | }; 141 | 18AB9F011BCE2C450049BF9F /* Frameworks */ = { 142 | isa = PBXFrameworksBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | A66C3BD8B4B3A8C21A75CE61 /* libPods-SwiftDemo.a in Frameworks */, 146 | ); 147 | runOnlyForDeploymentPostprocessing = 0; 148 | }; 149 | /* End PBXFrameworksBuildPhase section */ 150 | 151 | /* Begin PBXGroup section */ 152 | 180120E21BCE3001001069CC /* SCPageViewController */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | 180120E31BCE3001001069CC /* Layouters */, 156 | 180120ED1BCE3001001069CC /* SCPageViewController.h */, 157 | 180120EE1BCE3001001069CC /* SCPageViewController.m */, 158 | 180120EF1BCE3001001069CC /* SCPageViewControllerView.h */, 159 | 180120F01BCE3001001069CC /* SCPageViewControllerView.m */, 160 | ); 161 | name = SCPageViewController; 162 | path = ../SCPageViewController; 163 | sourceTree = ""; 164 | }; 165 | 180120E31BCE3001001069CC /* Layouters */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 180120E41BCE3001001069CC /* SCCardsPageLayouter.h */, 169 | 180120E51BCE3001001069CC /* SCCardsPageLayouter.m */, 170 | 180120E61BCE3001001069CC /* SCPageLayouter.h */, 171 | 180120E71BCE3001001069CC /* SCPageLayouter.m */, 172 | 180120E81BCE3001001069CC /* SCPageLayouterProtocol.h */, 173 | 180120E91BCE3001001069CC /* SCParallaxPageLayouter.h */, 174 | 180120EA1BCE3001001069CC /* SCParallaxPageLayouter.m */, 175 | 180120EB1BCE3001001069CC /* SCSlidingPageLayouter.h */, 176 | 180120EC1BCE3001001069CC /* SCSlidingPageLayouter.m */, 177 | ); 178 | path = Layouters; 179 | sourceTree = ""; 180 | }; 181 | 181957A61B37432800474C45 /* Tests */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | 181957B91B3743B600474C45 /* SCPageViewControllerTests.m */, 185 | 181957B81B3743B600474C45 /* SCPageLayouterTests.m */, 186 | 181957A71B37432800474C45 /* Supporting Files */, 187 | ); 188 | path = Tests; 189 | sourceTree = ""; 190 | }; 191 | 181957A71B37432800474C45 /* Supporting Files */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | 181957A81B37432800474C45 /* Info.plist */, 195 | ); 196 | name = "Supporting Files"; 197 | sourceTree = ""; 198 | }; 199 | 187E411A18A968E0003D8C70 = { 200 | isa = PBXGroup; 201 | children = ( 202 | 180120E21BCE3001001069CC /* SCPageViewController */, 203 | 187E412C18A968E0003D8C70 /* ObjCDemo */, 204 | 181957A61B37432800474C45 /* Tests */, 205 | 18AB9F051BCE2C460049BF9F /* SwiftDemo */, 206 | 187E412518A968E0003D8C70 /* Frameworks */, 207 | 187E412418A968E0003D8C70 /* Products */, 208 | 8F2725397AF5E19444B33442 /* Pods */, 209 | ); 210 | sourceTree = ""; 211 | }; 212 | 187E412418A968E0003D8C70 /* Products */ = { 213 | isa = PBXGroup; 214 | children = ( 215 | 187E412318A968E0003D8C70 /* ObjCDemo.app */, 216 | 181957A51B37432800474C45 /* Tests.xctest */, 217 | 18AB9F041BCE2C450049BF9F /* SwiftDemo.app */, 218 | ); 219 | name = Products; 220 | sourceTree = ""; 221 | }; 222 | 187E412518A968E0003D8C70 /* Frameworks */ = { 223 | isa = PBXGroup; 224 | children = ( 225 | 187E412618A968E0003D8C70 /* Foundation.framework */, 226 | 187E412818A968E0003D8C70 /* CoreGraphics.framework */, 227 | 187E412A18A968E0003D8C70 /* UIKit.framework */, 228 | 187E414518A968E0003D8C70 /* XCTest.framework */, 229 | 91696FFA725B1AFF96353D9A /* libPods-ObjCDemo.a */, 230 | C9CAE5D0D4CFCB88876D3233 /* libPods-SwiftDemo.a */, 231 | 5665E239FB8E5066CF4D7ADA /* libPods-Tests.a */, 232 | ); 233 | name = Frameworks; 234 | sourceTree = ""; 235 | }; 236 | 187E412C18A968E0003D8C70 /* ObjCDemo */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | 187E413518A968E0003D8C70 /* SCAppDelegate.h */, 240 | 187E413618A968E0003D8C70 /* SCAppDelegate.m */, 241 | 187E41C418A96A4E003D8C70 /* SCRootViewController.h */, 242 | 187E41C518A96A4E003D8C70 /* SCRootViewController.m */, 243 | 187E41CD18A96D2B003D8C70 /* SCRootViewController.xib */, 244 | 187E41BE18A96A4E003D8C70 /* SCMainViewController.h */, 245 | 187E41BF18A96A4E003D8C70 /* SCMainViewController.m */, 246 | 187E41C018A96A4E003D8C70 /* SCMainViewController.xib */, 247 | 187E41B918A96A4E003D8C70 /* Helpers */, 248 | 187E412D18A968E0003D8C70 /* Supporting Files */, 249 | ); 250 | path = ObjCDemo; 251 | sourceTree = ""; 252 | }; 253 | 187E412D18A968E0003D8C70 /* Supporting Files */ = { 254 | isa = PBXGroup; 255 | children = ( 256 | 18623FFD18B0063D00FFE998 /* colorful_umbrellas.jpg */, 257 | 187E412E18A968E0003D8C70 /* SCPageViewController-Info.plist */, 258 | 187E413218A968E0003D8C70 /* main.m */, 259 | 18E1DC361B39409F00361240 /* Launch Screen.xib */, 260 | ); 261 | name = "Supporting Files"; 262 | sourceTree = ""; 263 | }; 264 | 187E41B918A96A4E003D8C70 /* Helpers */ = { 265 | isa = PBXGroup; 266 | children = ( 267 | 187E41BA18A96A4E003D8C70 /* UIColor+RandomColors.h */, 268 | 187E41BB18A96A4E003D8C70 /* UIColor+RandomColors.m */, 269 | 187E41BC18A96A4E003D8C70 /* UIView+Shadows.h */, 270 | 187E41BD18A96A4E003D8C70 /* UIView+Shadows.m */, 271 | ); 272 | path = Helpers; 273 | sourceTree = ""; 274 | }; 275 | 18AB9F051BCE2C460049BF9F /* SwiftDemo */ = { 276 | isa = PBXGroup; 277 | children = ( 278 | 18AB9F061BCE2C460049BF9F /* AppDelegate.swift */, 279 | 18FA319A1BCE34C500134E86 /* RootViewController.swift */, 280 | 181FFE921C14474500DA2369 /* MainViewController.swift */, 281 | 181FFE931C14474500DA2369 /* MainViewController.xib */, 282 | 18AB9F161BCE2CFA0049BF9F /* Supporting Files */, 283 | 18AB9F1E1BCE2F0B0049BF9F /* SwiftDemo-Bridging-Header.h */, 284 | ); 285 | path = SwiftDemo; 286 | sourceTree = ""; 287 | }; 288 | 18AB9F161BCE2CFA0049BF9F /* Supporting Files */ = { 289 | isa = PBXGroup; 290 | children = ( 291 | 18AB9F171BCE2CFA0049BF9F /* Info.plist */, 292 | 18AB9F181BCE2CFA0049BF9F /* LaunchScreen.storyboard */, 293 | ); 294 | path = "Supporting Files"; 295 | sourceTree = ""; 296 | }; 297 | 8F2725397AF5E19444B33442 /* Pods */ = { 298 | isa = PBXGroup; 299 | children = ( 300 | 52A57530EE2FD7D1E3346871 /* Pods-ObjCDemo.debug.xcconfig */, 301 | 2A05B8BF4CD709715791CFDE /* Pods-ObjCDemo.release.xcconfig */, 302 | 178E2EF528419ADD8E0C7C0F /* Pods-SwiftDemo.debug.xcconfig */, 303 | 09819ACCCE4DE4FCEDC4C587 /* Pods-SwiftDemo.release.xcconfig */, 304 | F297DB8685EE6265766C484F /* Pods-Tests.debug.xcconfig */, 305 | D16B58900219A06FC8FB8E02 /* Pods-Tests.release.xcconfig */, 306 | ); 307 | name = Pods; 308 | sourceTree = ""; 309 | }; 310 | /* End PBXGroup section */ 311 | 312 | /* Begin PBXNativeTarget section */ 313 | 181957A41B37432800474C45 /* Tests */ = { 314 | isa = PBXNativeTarget; 315 | buildConfigurationList = 181957AD1B37432800474C45 /* Build configuration list for PBXNativeTarget "Tests" */; 316 | buildPhases = ( 317 | 6E54DCBDA50D7BD10F611294 /* [CP] Check Pods Manifest.lock */, 318 | 181957A11B37432800474C45 /* Sources */, 319 | 181957A21B37432800474C45 /* Frameworks */, 320 | 181957A31B37432800474C45 /* Resources */, 321 | 53C7E31A8AA7A4C6E465CF5D /* [CP] Embed Pods Frameworks */, 322 | EF27827ED8A6C0728EE2FE78 /* [CP] Copy Pods Resources */, 323 | ); 324 | buildRules = ( 325 | ); 326 | dependencies = ( 327 | 181957AC1B37432800474C45 /* PBXTargetDependency */, 328 | ); 329 | name = Tests; 330 | productName = Tests; 331 | productReference = 181957A51B37432800474C45 /* Tests.xctest */; 332 | productType = "com.apple.product-type.bundle.unit-test"; 333 | }; 334 | 187E412218A968E0003D8C70 /* ObjCDemo */ = { 335 | isa = PBXNativeTarget; 336 | buildConfigurationList = 187E415518A968E0003D8C70 /* Build configuration list for PBXNativeTarget "ObjCDemo" */; 337 | buildPhases = ( 338 | A291028CC9CCB70E3EBC9D06 /* [CP] Check Pods Manifest.lock */, 339 | 187E411F18A968E0003D8C70 /* Sources */, 340 | 187E412018A968E0003D8C70 /* Frameworks */, 341 | 187E412118A968E0003D8C70 /* Resources */, 342 | 237FF1CB1E7DC58CA871D208 /* [CP] Embed Pods Frameworks */, 343 | 31812AC9366049DB5D3F24C3 /* [CP] Copy Pods Resources */, 344 | ); 345 | buildRules = ( 346 | ); 347 | dependencies = ( 348 | ); 349 | name = ObjCDemo; 350 | productName = SCPageViewController; 351 | productReference = 187E412318A968E0003D8C70 /* ObjCDemo.app */; 352 | productType = "com.apple.product-type.application"; 353 | }; 354 | 18AB9F031BCE2C450049BF9F /* SwiftDemo */ = { 355 | isa = PBXNativeTarget; 356 | buildConfigurationList = 18AB9F151BCE2C460049BF9F /* Build configuration list for PBXNativeTarget "SwiftDemo" */; 357 | buildPhases = ( 358 | 3E77A5DC0AC53793A5643C2A /* [CP] Check Pods Manifest.lock */, 359 | 18AB9F001BCE2C450049BF9F /* Sources */, 360 | 18AB9F011BCE2C450049BF9F /* Frameworks */, 361 | 18AB9F021BCE2C450049BF9F /* Resources */, 362 | 5497E1AE2F74F495CFD9A66B /* [CP] Embed Pods Frameworks */, 363 | FE2EE060453879383389382E /* [CP] Copy Pods Resources */, 364 | ); 365 | buildRules = ( 366 | ); 367 | dependencies = ( 368 | ); 369 | name = SwiftDemo; 370 | productName = SwiftDemo; 371 | productReference = 18AB9F041BCE2C450049BF9F /* SwiftDemo.app */; 372 | productType = "com.apple.product-type.application"; 373 | }; 374 | /* End PBXNativeTarget section */ 375 | 376 | /* Begin PBXProject section */ 377 | 187E411B18A968E0003D8C70 /* Project object */ = { 378 | isa = PBXProject; 379 | attributes = { 380 | CLASSPREFIX = SC; 381 | LastSwiftUpdateCheck = 0700; 382 | LastUpgradeCheck = 0710; 383 | ORGANIZATIONNAME = "Stefan Ceriu"; 384 | TargetAttributes = { 385 | 181957A41B37432800474C45 = { 386 | CreatedOnToolsVersion = 6.3.2; 387 | TestTargetID = 187E412218A968E0003D8C70; 388 | }; 389 | 18AB9F031BCE2C450049BF9F = { 390 | CreatedOnToolsVersion = 7.0; 391 | LastSwiftMigration = 0810; 392 | }; 393 | }; 394 | }; 395 | buildConfigurationList = 187E411E18A968E0003D8C70 /* Build configuration list for PBXProject "SCPageViewController" */; 396 | compatibilityVersion = "Xcode 3.2"; 397 | developmentRegion = English; 398 | hasScannedForEncodings = 0; 399 | knownRegions = ( 400 | en, 401 | Base, 402 | ); 403 | mainGroup = 187E411A18A968E0003D8C70; 404 | productRefGroup = 187E412418A968E0003D8C70 /* Products */; 405 | projectDirPath = ""; 406 | projectRoot = ""; 407 | targets = ( 408 | 187E412218A968E0003D8C70 /* ObjCDemo */, 409 | 18AB9F031BCE2C450049BF9F /* SwiftDemo */, 410 | 181957A41B37432800474C45 /* Tests */, 411 | ); 412 | }; 413 | /* End PBXProject section */ 414 | 415 | /* Begin PBXResourcesBuildPhase section */ 416 | 181957A31B37432800474C45 /* Resources */ = { 417 | isa = PBXResourcesBuildPhase; 418 | buildActionMask = 2147483647; 419 | files = ( 420 | ); 421 | runOnlyForDeploymentPostprocessing = 0; 422 | }; 423 | 187E412118A968E0003D8C70 /* Resources */ = { 424 | isa = PBXResourcesBuildPhase; 425 | buildActionMask = 2147483647; 426 | files = ( 427 | 187E41C918A96A4E003D8C70 /* SCMainViewController.xib in Resources */, 428 | 18E1DC371B39409F00361240 /* Launch Screen.xib in Resources */, 429 | 18623FFE18B0063D00FFE998 /* colorful_umbrellas.jpg in Resources */, 430 | 187E41CE18A96D2B003D8C70 /* SCRootViewController.xib in Resources */, 431 | ); 432 | runOnlyForDeploymentPostprocessing = 0; 433 | }; 434 | 18AB9F021BCE2C450049BF9F /* Resources */ = { 435 | isa = PBXResourcesBuildPhase; 436 | buildActionMask = 2147483647; 437 | files = ( 438 | 181FFE951C14474500DA2369 /* MainViewController.xib in Resources */, 439 | 18AB9F1A1BCE2CFA0049BF9F /* LaunchScreen.storyboard in Resources */, 440 | ); 441 | runOnlyForDeploymentPostprocessing = 0; 442 | }; 443 | /* End PBXResourcesBuildPhase section */ 444 | 445 | /* Begin PBXShellScriptBuildPhase section */ 446 | 237FF1CB1E7DC58CA871D208 /* [CP] Embed Pods Frameworks */ = { 447 | isa = PBXShellScriptBuildPhase; 448 | buildActionMask = 2147483647; 449 | files = ( 450 | ); 451 | inputPaths = ( 452 | ); 453 | name = "[CP] Embed Pods Frameworks"; 454 | outputPaths = ( 455 | ); 456 | runOnlyForDeploymentPostprocessing = 0; 457 | shellPath = /bin/sh; 458 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ObjCDemo/Pods-ObjCDemo-frameworks.sh\"\n"; 459 | showEnvVarsInLog = 0; 460 | }; 461 | 31812AC9366049DB5D3F24C3 /* [CP] Copy Pods Resources */ = { 462 | isa = PBXShellScriptBuildPhase; 463 | buildActionMask = 2147483647; 464 | files = ( 465 | ); 466 | inputPaths = ( 467 | ); 468 | name = "[CP] Copy Pods Resources"; 469 | outputPaths = ( 470 | ); 471 | runOnlyForDeploymentPostprocessing = 0; 472 | shellPath = /bin/sh; 473 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ObjCDemo/Pods-ObjCDemo-resources.sh\"\n"; 474 | showEnvVarsInLog = 0; 475 | }; 476 | 3E77A5DC0AC53793A5643C2A /* [CP] Check Pods Manifest.lock */ = { 477 | isa = PBXShellScriptBuildPhase; 478 | buildActionMask = 2147483647; 479 | files = ( 480 | ); 481 | inputPaths = ( 482 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 483 | "${PODS_ROOT}/Manifest.lock", 484 | ); 485 | name = "[CP] Check Pods Manifest.lock"; 486 | outputPaths = ( 487 | "$(DERIVED_FILE_DIR)/Pods-SwiftDemo-checkManifestLockResult.txt", 488 | ); 489 | runOnlyForDeploymentPostprocessing = 0; 490 | shellPath = /bin/sh; 491 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 492 | showEnvVarsInLog = 0; 493 | }; 494 | 53C7E31A8AA7A4C6E465CF5D /* [CP] Embed Pods Frameworks */ = { 495 | isa = PBXShellScriptBuildPhase; 496 | buildActionMask = 2147483647; 497 | files = ( 498 | ); 499 | inputPaths = ( 500 | ); 501 | name = "[CP] Embed Pods Frameworks"; 502 | outputPaths = ( 503 | ); 504 | runOnlyForDeploymentPostprocessing = 0; 505 | shellPath = /bin/sh; 506 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n"; 507 | showEnvVarsInLog = 0; 508 | }; 509 | 5497E1AE2F74F495CFD9A66B /* [CP] Embed Pods Frameworks */ = { 510 | isa = PBXShellScriptBuildPhase; 511 | buildActionMask = 2147483647; 512 | files = ( 513 | ); 514 | inputPaths = ( 515 | ); 516 | name = "[CP] Embed Pods Frameworks"; 517 | outputPaths = ( 518 | ); 519 | runOnlyForDeploymentPostprocessing = 0; 520 | shellPath = /bin/sh; 521 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo-frameworks.sh\"\n"; 522 | showEnvVarsInLog = 0; 523 | }; 524 | 6E54DCBDA50D7BD10F611294 /* [CP] Check Pods Manifest.lock */ = { 525 | isa = PBXShellScriptBuildPhase; 526 | buildActionMask = 2147483647; 527 | files = ( 528 | ); 529 | inputPaths = ( 530 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 531 | "${PODS_ROOT}/Manifest.lock", 532 | ); 533 | name = "[CP] Check Pods Manifest.lock"; 534 | outputPaths = ( 535 | "$(DERIVED_FILE_DIR)/Pods-Tests-checkManifestLockResult.txt", 536 | ); 537 | runOnlyForDeploymentPostprocessing = 0; 538 | shellPath = /bin/sh; 539 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 540 | showEnvVarsInLog = 0; 541 | }; 542 | A291028CC9CCB70E3EBC9D06 /* [CP] Check Pods Manifest.lock */ = { 543 | isa = PBXShellScriptBuildPhase; 544 | buildActionMask = 2147483647; 545 | files = ( 546 | ); 547 | inputPaths = ( 548 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 549 | "${PODS_ROOT}/Manifest.lock", 550 | ); 551 | name = "[CP] Check Pods Manifest.lock"; 552 | outputPaths = ( 553 | "$(DERIVED_FILE_DIR)/Pods-ObjCDemo-checkManifestLockResult.txt", 554 | ); 555 | runOnlyForDeploymentPostprocessing = 0; 556 | shellPath = /bin/sh; 557 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 558 | showEnvVarsInLog = 0; 559 | }; 560 | EF27827ED8A6C0728EE2FE78 /* [CP] Copy Pods Resources */ = { 561 | isa = PBXShellScriptBuildPhase; 562 | buildActionMask = 2147483647; 563 | files = ( 564 | ); 565 | inputPaths = ( 566 | ); 567 | name = "[CP] Copy Pods Resources"; 568 | outputPaths = ( 569 | ); 570 | runOnlyForDeploymentPostprocessing = 0; 571 | shellPath = /bin/sh; 572 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n"; 573 | showEnvVarsInLog = 0; 574 | }; 575 | FE2EE060453879383389382E /* [CP] Copy Pods Resources */ = { 576 | isa = PBXShellScriptBuildPhase; 577 | buildActionMask = 2147483647; 578 | files = ( 579 | ); 580 | inputPaths = ( 581 | ); 582 | name = "[CP] Copy Pods Resources"; 583 | outputPaths = ( 584 | ); 585 | runOnlyForDeploymentPostprocessing = 0; 586 | shellPath = /bin/sh; 587 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwiftDemo/Pods-SwiftDemo-resources.sh\"\n"; 588 | showEnvVarsInLog = 0; 589 | }; 590 | /* End PBXShellScriptBuildPhase section */ 591 | 592 | /* Begin PBXSourcesBuildPhase section */ 593 | 181957A11B37432800474C45 /* Sources */ = { 594 | isa = PBXSourcesBuildPhase; 595 | buildActionMask = 2147483647; 596 | files = ( 597 | 181957BC1B3743B600474C45 /* SCPageLayouterTests.m in Sources */, 598 | 180120F91BCE3042001069CC /* SCPageViewControllerView.m in Sources */, 599 | 181957BD1B3743B600474C45 /* SCPageViewControllerTests.m in Sources */, 600 | 180120FB1BCE304E001069CC /* SCCardsPageLayouter.m in Sources */, 601 | 180120FE1BCE304E001069CC /* SCSlidingPageLayouter.m in Sources */, 602 | 180120FD1BCE304E001069CC /* SCParallaxPageLayouter.m in Sources */, 603 | 180120FA1BCE3045001069CC /* SCPageViewController.m in Sources */, 604 | 180120FC1BCE304E001069CC /* SCPageLayouter.m in Sources */, 605 | ); 606 | runOnlyForDeploymentPostprocessing = 0; 607 | }; 608 | 187E411F18A968E0003D8C70 /* Sources */ = { 609 | isa = PBXSourcesBuildPhase; 610 | buildActionMask = 2147483647; 611 | files = ( 612 | 187E413718A968E0003D8C70 /* SCAppDelegate.m in Sources */, 613 | 180120F71BCE303E001069CC /* SCPageViewController.m in Sources */, 614 | 180120FF1BCE304F001069CC /* SCCardsPageLayouter.m in Sources */, 615 | 180120F81BCE3041001069CC /* SCPageViewControllerView.m in Sources */, 616 | 180121021BCE304F001069CC /* SCSlidingPageLayouter.m in Sources */, 617 | 180121011BCE304F001069CC /* SCParallaxPageLayouter.m in Sources */, 618 | 187E41C618A96A4E003D8C70 /* UIColor+RandomColors.m in Sources */, 619 | 180121001BCE304F001069CC /* SCPageLayouter.m in Sources */, 620 | 187E413318A968E0003D8C70 /* main.m in Sources */, 621 | 187E41C818A96A4E003D8C70 /* SCMainViewController.m in Sources */, 622 | 187E41C718A96A4E003D8C70 /* UIView+Shadows.m in Sources */, 623 | 187E41CC18A96A4E003D8C70 /* SCRootViewController.m in Sources */, 624 | ); 625 | runOnlyForDeploymentPostprocessing = 0; 626 | }; 627 | 18AB9F001BCE2C450049BF9F /* Sources */ = { 628 | isa = PBXSourcesBuildPhase; 629 | buildActionMask = 2147483647; 630 | files = ( 631 | 18FA31981BCE318800134E86 /* SCPageViewController.m in Sources */, 632 | 18FA319B1BCE34C500134E86 /* RootViewController.swift in Sources */, 633 | 18FA31991BCE318800134E86 /* SCPageViewControllerView.m in Sources */, 634 | 18AB9F071BCE2C460049BF9F /* AppDelegate.swift in Sources */, 635 | 18FA31941BCE318800134E86 /* SCCardsPageLayouter.m in Sources */, 636 | 18FA31951BCE318800134E86 /* SCPageLayouter.m in Sources */, 637 | 181FFE941C14474500DA2369 /* MainViewController.swift in Sources */, 638 | 18FA31971BCE318800134E86 /* SCSlidingPageLayouter.m in Sources */, 639 | 18FA31961BCE318800134E86 /* SCParallaxPageLayouter.m in Sources */, 640 | ); 641 | runOnlyForDeploymentPostprocessing = 0; 642 | }; 643 | /* End PBXSourcesBuildPhase section */ 644 | 645 | /* Begin PBXTargetDependency section */ 646 | 181957AC1B37432800474C45 /* PBXTargetDependency */ = { 647 | isa = PBXTargetDependency; 648 | target = 187E412218A968E0003D8C70 /* ObjCDemo */; 649 | targetProxy = 181957AB1B37432800474C45 /* PBXContainerItemProxy */; 650 | }; 651 | /* End PBXTargetDependency section */ 652 | 653 | /* Begin XCBuildConfiguration section */ 654 | 181957AE1B37432800474C45 /* Debug */ = { 655 | isa = XCBuildConfiguration; 656 | baseConfigurationReference = F297DB8685EE6265766C484F /* Pods-Tests.debug.xcconfig */; 657 | buildSettings = { 658 | BUNDLE_LOADER = "$(TEST_HOST)"; 659 | CLANG_WARN_UNREACHABLE_CODE = YES; 660 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 661 | ENABLE_STRICT_OBJC_MSGSEND = YES; 662 | FRAMEWORK_SEARCH_PATHS = ( 663 | "$(SDKROOT)/Developer/Library/Frameworks", 664 | "$(inherited)", 665 | ); 666 | GCC_NO_COMMON_BLOCKS = YES; 667 | GCC_PREPROCESSOR_DEFINITIONS = ( 668 | "DEBUG=1", 669 | "$(inherited)", 670 | ); 671 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 672 | INFOPLIST_FILE = Tests/Info.plist; 673 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 674 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 675 | MTL_ENABLE_DEBUG_INFO = YES; 676 | PRODUCT_BUNDLE_IDENTIFIER = "com.stefanceriu.$(PRODUCT_NAME:rfc1034identifier)"; 677 | PRODUCT_NAME = "$(TARGET_NAME)"; 678 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ObjCDemo.app/ObjCDemo"; 679 | }; 680 | name = Debug; 681 | }; 682 | 181957AF1B37432800474C45 /* Release */ = { 683 | isa = XCBuildConfiguration; 684 | baseConfigurationReference = D16B58900219A06FC8FB8E02 /* Pods-Tests.release.xcconfig */; 685 | buildSettings = { 686 | BUNDLE_LOADER = "$(TEST_HOST)"; 687 | CLANG_WARN_UNREACHABLE_CODE = YES; 688 | COPY_PHASE_STRIP = NO; 689 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 690 | ENABLE_STRICT_OBJC_MSGSEND = YES; 691 | FRAMEWORK_SEARCH_PATHS = ( 692 | "$(SDKROOT)/Developer/Library/Frameworks", 693 | "$(inherited)", 694 | ); 695 | GCC_NO_COMMON_BLOCKS = YES; 696 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 697 | INFOPLIST_FILE = Tests/Info.plist; 698 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 699 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 700 | MTL_ENABLE_DEBUG_INFO = NO; 701 | PRODUCT_BUNDLE_IDENTIFIER = "com.stefanceriu.$(PRODUCT_NAME:rfc1034identifier)"; 702 | PRODUCT_NAME = "$(TARGET_NAME)"; 703 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ObjCDemo.app/ObjCDemo"; 704 | }; 705 | name = Release; 706 | }; 707 | 187E415318A968E0003D8C70 /* Debug */ = { 708 | isa = XCBuildConfiguration; 709 | buildSettings = { 710 | ALWAYS_SEARCH_USER_PATHS = NO; 711 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 712 | CLANG_CXX_LIBRARY = "libc++"; 713 | CLANG_ENABLE_MODULES = YES; 714 | CLANG_ENABLE_OBJC_ARC = YES; 715 | CLANG_WARN_BOOL_CONVERSION = YES; 716 | CLANG_WARN_CONSTANT_CONVERSION = YES; 717 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 718 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 719 | CLANG_WARN_EMPTY_BODY = YES; 720 | CLANG_WARN_ENUM_CONVERSION = YES; 721 | CLANG_WARN_INT_CONVERSION = YES; 722 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 723 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 724 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 725 | COPY_PHASE_STRIP = NO; 726 | ENABLE_TESTABILITY = YES; 727 | GCC_C_LANGUAGE_STANDARD = gnu99; 728 | GCC_DYNAMIC_NO_PIC = NO; 729 | GCC_OPTIMIZATION_LEVEL = 0; 730 | GCC_PREPROCESSOR_DEFINITIONS = ( 731 | "DEBUG=1", 732 | "$(inherited)", 733 | ); 734 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 735 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 736 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 737 | GCC_WARN_UNDECLARED_SELECTOR = YES; 738 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 739 | GCC_WARN_UNUSED_FUNCTION = YES; 740 | GCC_WARN_UNUSED_VARIABLE = YES; 741 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 742 | ONLY_ACTIVE_ARCH = YES; 743 | SDKROOT = iphoneos; 744 | TARGETED_DEVICE_FAMILY = 2; 745 | }; 746 | name = Debug; 747 | }; 748 | 187E415418A968E0003D8C70 /* Release */ = { 749 | isa = XCBuildConfiguration; 750 | buildSettings = { 751 | ALWAYS_SEARCH_USER_PATHS = NO; 752 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 753 | CLANG_CXX_LIBRARY = "libc++"; 754 | CLANG_ENABLE_MODULES = YES; 755 | CLANG_ENABLE_OBJC_ARC = YES; 756 | CLANG_WARN_BOOL_CONVERSION = YES; 757 | CLANG_WARN_CONSTANT_CONVERSION = YES; 758 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 759 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 760 | CLANG_WARN_EMPTY_BODY = YES; 761 | CLANG_WARN_ENUM_CONVERSION = YES; 762 | CLANG_WARN_INT_CONVERSION = YES; 763 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 764 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 765 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 766 | COPY_PHASE_STRIP = YES; 767 | ENABLE_NS_ASSERTIONS = NO; 768 | GCC_C_LANGUAGE_STANDARD = gnu99; 769 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 770 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 771 | GCC_WARN_UNDECLARED_SELECTOR = YES; 772 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 773 | GCC_WARN_UNUSED_FUNCTION = YES; 774 | GCC_WARN_UNUSED_VARIABLE = YES; 775 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 776 | SDKROOT = iphoneos; 777 | TARGETED_DEVICE_FAMILY = 2; 778 | VALIDATE_PRODUCT = YES; 779 | }; 780 | name = Release; 781 | }; 782 | 187E415618A968E0003D8C70 /* Debug */ = { 783 | isa = XCBuildConfiguration; 784 | baseConfigurationReference = 52A57530EE2FD7D1E3346871 /* Pods-ObjCDemo.debug.xcconfig */; 785 | buildSettings = { 786 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 787 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 788 | CLANG_WARN_ASSIGN_ENUM = YES; 789 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES_ERROR; 790 | CLANG_WARN_COMMA = YES; 791 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 792 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 793 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = NO; 794 | CLANG_WARN_INFINITE_RECURSION = YES; 795 | CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; 796 | CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = NO; 797 | CLANG_WARN_STRICT_PROTOTYPES = YES; 798 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO; 799 | CLANG_WARN_UNREACHABLE_CODE = YES; 800 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 801 | GCC_PREFIX_HEADER = ""; 802 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; 803 | GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; 804 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 805 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 806 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 807 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; 808 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 809 | GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; 810 | GCC_WARN_SHADOW = YES; 811 | GCC_WARN_SIGN_COMPARE = NO; 812 | GCC_WARN_STRICT_SELECTOR_MATCH = YES; 813 | GCC_WARN_UNKNOWN_PRAGMAS = YES; 814 | GCC_WARN_UNUSED_LABEL = YES; 815 | GCC_WARN_UNUSED_PARAMETER = NO; 816 | HEADER_SEARCH_PATHS = "$(inherited)"; 817 | INFOPLIST_FILE = "ObjCDemo/SCPageViewController-Info.plist"; 818 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 819 | PRODUCT_BUNDLE_IDENTIFIER = "com.stefanceriu.${PRODUCT_NAME:rfc1034identifier}"; 820 | PRODUCT_NAME = "$(TARGET_NAME)"; 821 | TARGETED_DEVICE_FAMILY = "1,2"; 822 | WRAPPER_EXTENSION = app; 823 | }; 824 | name = Debug; 825 | }; 826 | 187E415718A968E0003D8C70 /* Release */ = { 827 | isa = XCBuildConfiguration; 828 | baseConfigurationReference = 2A05B8BF4CD709715791CFDE /* Pods-ObjCDemo.release.xcconfig */; 829 | buildSettings = { 830 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 831 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 832 | CLANG_WARN_ASSIGN_ENUM = YES; 833 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES_ERROR; 834 | CLANG_WARN_COMMA = YES; 835 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 836 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 837 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = NO; 838 | CLANG_WARN_INFINITE_RECURSION = YES; 839 | CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; 840 | CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = NO; 841 | CLANG_WARN_STRICT_PROTOTYPES = YES; 842 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = NO; 843 | CLANG_WARN_UNREACHABLE_CODE = YES; 844 | GCC_PRECOMPILE_PREFIX_HEADER = NO; 845 | GCC_PREFIX_HEADER = ""; 846 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; 847 | GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; 848 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES; 849 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES; 850 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 851 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; 852 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; 853 | GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES; 854 | GCC_WARN_SHADOW = YES; 855 | GCC_WARN_SIGN_COMPARE = NO; 856 | GCC_WARN_STRICT_SELECTOR_MATCH = YES; 857 | GCC_WARN_UNKNOWN_PRAGMAS = YES; 858 | GCC_WARN_UNUSED_LABEL = YES; 859 | GCC_WARN_UNUSED_PARAMETER = NO; 860 | HEADER_SEARCH_PATHS = "$(inherited)"; 861 | INFOPLIST_FILE = "ObjCDemo/SCPageViewController-Info.plist"; 862 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 863 | PRODUCT_BUNDLE_IDENTIFIER = "com.stefanceriu.${PRODUCT_NAME:rfc1034identifier}"; 864 | PRODUCT_NAME = "$(TARGET_NAME)"; 865 | TARGETED_DEVICE_FAMILY = "1,2"; 866 | WRAPPER_EXTENSION = app; 867 | }; 868 | name = Release; 869 | }; 870 | 18AB9F131BCE2C460049BF9F /* Debug */ = { 871 | isa = XCBuildConfiguration; 872 | baseConfigurationReference = 178E2EF528419ADD8E0C7C0F /* Pods-SwiftDemo.debug.xcconfig */; 873 | buildSettings = { 874 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 875 | CLANG_ENABLE_MODULES = YES; 876 | CLANG_WARN_UNREACHABLE_CODE = YES; 877 | DEBUG_INFORMATION_FORMAT = dwarf; 878 | ENABLE_STRICT_OBJC_MSGSEND = YES; 879 | ENABLE_TESTABILITY = YES; 880 | GCC_NO_COMMON_BLOCKS = YES; 881 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 882 | HEADER_SEARCH_PATHS = "$(inherited)"; 883 | INFOPLIST_FILE = "SwiftDemo/Supporting Files/Info.plist"; 884 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 885 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 886 | MTL_ENABLE_DEBUG_INFO = YES; 887 | PRODUCT_BUNDLE_IDENTIFIER = com.stefanceriu.SwiftDemo; 888 | PRODUCT_NAME = "$(TARGET_NAME)"; 889 | SWIFT_OBJC_BRIDGING_HEADER = "SwiftDemo/SwiftDemo-Bridging-Header.h"; 890 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 891 | SWIFT_VERSION = 3.0; 892 | TARGETED_DEVICE_FAMILY = "1,2"; 893 | }; 894 | name = Debug; 895 | }; 896 | 18AB9F141BCE2C460049BF9F /* Release */ = { 897 | isa = XCBuildConfiguration; 898 | baseConfigurationReference = 09819ACCCE4DE4FCEDC4C587 /* Pods-SwiftDemo.release.xcconfig */; 899 | buildSettings = { 900 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 901 | CLANG_ENABLE_MODULES = YES; 902 | CLANG_WARN_UNREACHABLE_CODE = YES; 903 | COPY_PHASE_STRIP = NO; 904 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 905 | ENABLE_STRICT_OBJC_MSGSEND = YES; 906 | GCC_NO_COMMON_BLOCKS = YES; 907 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 908 | HEADER_SEARCH_PATHS = "$(inherited)"; 909 | INFOPLIST_FILE = "SwiftDemo/Supporting Files/Info.plist"; 910 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 911 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 912 | MTL_ENABLE_DEBUG_INFO = NO; 913 | PRODUCT_BUNDLE_IDENTIFIER = com.stefanceriu.SwiftDemo; 914 | PRODUCT_NAME = "$(TARGET_NAME)"; 915 | SWIFT_OBJC_BRIDGING_HEADER = "SwiftDemo/SwiftDemo-Bridging-Header.h"; 916 | SWIFT_VERSION = 3.0; 917 | TARGETED_DEVICE_FAMILY = "1,2"; 918 | }; 919 | name = Release; 920 | }; 921 | /* End XCBuildConfiguration section */ 922 | 923 | /* Begin XCConfigurationList section */ 924 | 181957AD1B37432800474C45 /* Build configuration list for PBXNativeTarget "Tests" */ = { 925 | isa = XCConfigurationList; 926 | buildConfigurations = ( 927 | 181957AE1B37432800474C45 /* Debug */, 928 | 181957AF1B37432800474C45 /* Release */, 929 | ); 930 | defaultConfigurationIsVisible = 0; 931 | defaultConfigurationName = Release; 932 | }; 933 | 187E411E18A968E0003D8C70 /* Build configuration list for PBXProject "SCPageViewController" */ = { 934 | isa = XCConfigurationList; 935 | buildConfigurations = ( 936 | 187E415318A968E0003D8C70 /* Debug */, 937 | 187E415418A968E0003D8C70 /* Release */, 938 | ); 939 | defaultConfigurationIsVisible = 0; 940 | defaultConfigurationName = Release; 941 | }; 942 | 187E415518A968E0003D8C70 /* Build configuration list for PBXNativeTarget "ObjCDemo" */ = { 943 | isa = XCConfigurationList; 944 | buildConfigurations = ( 945 | 187E415618A968E0003D8C70 /* Debug */, 946 | 187E415718A968E0003D8C70 /* Release */, 947 | ); 948 | defaultConfigurationIsVisible = 0; 949 | defaultConfigurationName = Release; 950 | }; 951 | 18AB9F151BCE2C460049BF9F /* Build configuration list for PBXNativeTarget "SwiftDemo" */ = { 952 | isa = XCConfigurationList; 953 | buildConfigurations = ( 954 | 18AB9F131BCE2C460049BF9F /* Debug */, 955 | 18AB9F141BCE2C460049BF9F /* Release */, 956 | ); 957 | defaultConfigurationIsVisible = 0; 958 | defaultConfigurationName = Release; 959 | }; 960 | /* End XCConfigurationList section */ 961 | }; 962 | rootObject = 187E411B18A968E0003D8C70 /* Project object */; 963 | } 964 | --------------------------------------------------------------------------------