├── .DS_Store
├── IntroductionExample
├── en.lproj
│ ├── InfoPlist.strings
│ └── MYViewController.xib
├── Default.png
├── Default@2x.png
├── SampleImage1.png
├── SampleImage2.png
├── Default-568h@2x.png
├── SampleBackground.png
├── SampleHeaderImage.png
├── IntroductionExample-Prefix.pch
├── main.m
├── MYViewController.h
├── MYAppDelegate.h
├── MYIntroductionPanel.h
├── IntroductionExample-Info.plist
├── MYIntroductionPanel.m
├── MYAppDelegate.m
├── MYIntroductionView.h
├── MYViewController.m
└── MYIntroductionView.m
├── IntroductionExample.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ ├── Ryan.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ ├── shams.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ └── matthewyork.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── WorkspaceSettings.xcsettings
├── xcuserdata
│ ├── Ryan.xcuserdatad
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── IntroductionExample.xcscheme
│ ├── shams.xcuserdatad
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── IntroductionExample.xcscheme
│ └── matthewyork.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── IntroductionExample.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints.xcbkptlist
└── project.pbxproj
├── .gitignore
├── MYIntroduction.podspec
├── LICENSE
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/.DS_Store
--------------------------------------------------------------------------------
/IntroductionExample/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/IntroductionExample/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample/Default.png
--------------------------------------------------------------------------------
/IntroductionExample/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample/Default@2x.png
--------------------------------------------------------------------------------
/IntroductionExample/SampleImage1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample/SampleImage1.png
--------------------------------------------------------------------------------
/IntroductionExample/SampleImage2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample/SampleImage2.png
--------------------------------------------------------------------------------
/IntroductionExample/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample/Default-568h@2x.png
--------------------------------------------------------------------------------
/IntroductionExample/SampleBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample/SampleBackground.png
--------------------------------------------------------------------------------
/IntroductionExample/SampleHeaderImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample/SampleHeaderImage.png
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/project.xcworkspace/xcuserdata/Ryan.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample.xcodeproj/project.xcworkspace/xcuserdata/Ryan.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/project.xcworkspace/xcuserdata/shams.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample.xcodeproj/project.xcworkspace/xcuserdata/shams.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/project.xcworkspace/xcuserdata/matthewyork.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Todo/iPhone-IntroductionTutorial/master/IntroductionExample.xcodeproj/project.xcworkspace/xcuserdata/matthewyork.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/IntroductionExample/IntroductionExample-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'IntroductionExample' target in the 'IntroductionExample' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_4_0
8 | #warning "This project uses features only available in iOS SDK 4.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/.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 | *.xcuserstate
20 | XXX.xcodeproj/project.xcworkspace/xcuserdata/xxx.xcuserdatad/UserInterfaceState.xcuserstate
21 | *.xcuserstate
22 |
--------------------------------------------------------------------------------
/IntroductionExample/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // IntroductionExample
4 | //
5 | // Created by Matthew York on 3/6/13.
6 | // Copyright (c) 2013 Matthew York. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "MYAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([MYAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/project.xcworkspace/xcuserdata/matthewyork.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/xcuserdata/Ryan.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | IntroductionExample.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | F02BB21016E847B400E3D502
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/xcuserdata/shams.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | IntroductionExample.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | F02BB21016E847B400E3D502
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/xcuserdata/matthewyork.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | IntroductionExample.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | F02BB21016E847B400E3D502
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/MYIntroduction.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'MYIntroduction'
3 | s.version = '0.0.1'
4 | s.summary = 'Solution for building stylish app introductions and tutorials.'
5 | s.homepage = 'https://github.com/MatthewYork/iPhone-IntroductionTutorial'
6 |
7 | s.description = 'A "drop-in" solution for building stylish app introductions and tutorials. ' \
8 | 'Now supports left-to-right and right-to-left languages.'
9 |
10 | s.license = { :type => 'MIT', :file => 'LICENSE' }
11 | s.author = { "Matthew York" => "my3681@gmail.com" }
12 |
13 | s.source = { :git => "https://github.com/MatthewYork/iPhone-IntroductionTutorial.git",
14 | :commit => "cd60cebb0f63fdbf94b89fe7ebbf6bffc0b67eeb" }
15 |
16 | s.platform = :ios, '5.0'
17 | s.requires_arc = true
18 |
19 | s.source_files = 'IntroductionExample/MYIntroduction{Panel,View}.{h,m}'
20 | s.frameworks = 'QuartzCore'
21 | end
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2013 by Matthew York
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/IntroductionExample/MYViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // MYViewController.h
3 | // IntroductionExample
4 | //
5 | // Copyright (C) 2013, Matt York
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | // this software and associated documentation files (the "Software"), to deal in
9 | // the Software without restriction, including without limitation the rights to
10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | // of the Software, and to permit persons to whom the Software is furnished to do
12 | // so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in all
15 | // copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | #import
27 | #import "MYIntroductionView.h"
28 |
29 | @interface MYViewController : UIViewController
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/IntroductionExample/MYAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // MYAppDelegate.h
3 | // IntroductionExample
4 | //
5 | // Copyright (C) 2013, Matt York
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | // this software and associated documentation files (the "Software"), to deal in
9 | // the Software without restriction, including without limitation the rights to
10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | // of the Software, and to permit persons to whom the Software is furnished to do
12 | // so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in all
15 | // copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | #import
27 |
28 | @class MYViewController;
29 |
30 | @interface MYAppDelegate : UIResponder
31 |
32 | @property (strong, nonatomic) UIWindow *window;
33 |
34 | @property (strong, nonatomic) MYViewController *viewController;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/IntroductionExample/MYIntroductionPanel.h:
--------------------------------------------------------------------------------
1 | //
2 | // MYIntroductionPanel.h
3 | // IntroductionExample
4 | //
5 | // Copyright (C) 2013, Matt York
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | // this software and associated documentation files (the "Software"), to deal in
9 | // the Software without restriction, including without limitation the rights to
10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | // of the Software, and to permit persons to whom the Software is furnished to do
12 | // so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in all
15 | // copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | #import
27 |
28 | @interface MYIntroductionPanel : NSObject
29 |
30 | //Image
31 | @property (nonatomic, retain) UIImage *Image;
32 |
33 | //Title
34 | @property (nonatomic, retain) NSString *Title;
35 |
36 | //Description
37 | @property (nonatomic, retain) NSString *Description;
38 |
39 | //Custom init method
40 | -(id)initWithimage:(UIImage *)image title:(NSString *)title description:(NSString *)description;
41 | -(id)initWithimage:(UIImage *)image description:(NSString *)description;
42 |
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/IntroductionExample/IntroductionExample-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Introduction
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIcons
12 |
13 | CFBundlePrimaryIcon
14 |
15 | CFBundleIconFiles
16 |
17 |
18 |
19 | CFBundleIdentifier
20 | com.mattyork.${PRODUCT_NAME:rfc1034identifier}
21 | CFBundleInfoDictionaryVersion
22 | 6.0
23 | CFBundleName
24 | Introduction
25 | CFBundlePackageType
26 | APPL
27 | CFBundleShortVersionString
28 | 1.0
29 | CFBundleSignature
30 | ????
31 | CFBundleVersion
32 | 1.0
33 | LSRequiresIPhoneOS
34 |
35 | UIRequiredDeviceCapabilities
36 |
37 | armv7
38 |
39 | UISupportedInterfaceOrientations
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | UISupportedInterfaceOrientations~ipad
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationPortraitUpsideDown
51 | UIInterfaceOrientationLandscapeRight
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/IntroductionExample/MYIntroductionPanel.m:
--------------------------------------------------------------------------------
1 | //
2 | // MYIntroductionPanel.m
3 | // IntroductionExample
4 | //
5 | // Copyright (C) 2013, Matt York
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | // this software and associated documentation files (the "Software"), to deal in
9 | // the Software without restriction, including without limitation the rights to
10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | // of the Software, and to permit persons to whom the Software is furnished to do
12 | // so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in all
15 | // copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | #import "MYIntroductionPanel.h"
27 |
28 | @implementation MYIntroductionPanel
29 |
30 | -(id)initWithimage:(UIImage *)image title:(NSString *)title description:(NSString *)description{
31 | if (self = [super init]) {
32 | //Set panel Image
33 | self.Image = [[UIImage alloc] init];
34 | self.Image = image;
35 | self.Title = title;
36 |
37 | //Set panel Description
38 | self.Description = [[NSString alloc] initWithString:description];
39 | }
40 | return self;
41 | }
42 |
43 | -(id)initWithimage:(UIImage *)image description:(NSString *)description{
44 | if (self = [super init]) {
45 | //Set panel Image
46 | self.Image = [[UIImage alloc] init];
47 | self.Image = image;
48 | self.Title = @"";
49 |
50 | //Set panel Description
51 | self.Description = [[NSString alloc] initWithString:description];
52 | }
53 | return self;
54 | }
55 |
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | iPhone Introduction / Tutorial (MYIntroductionView)
2 | ================================
3 |
4 | 
5 | 
6 |
7 | Everyone needs them and everyone hates writing them... Yes, it's the tutorial screen! I got sick of writing one for every app I made, so I went ahead and standardized it here.
8 |
9 | Features Include:
10 | - Left-to-Right and Right-to-Left language support
11 | - Delegate methods for handling current page and completion events
12 | - Easy UIView implementation that works with or without storyboards
13 |
14 | CocoaPods
15 | ========================
16 | If you use CocoaPods, you can install MYIntroduction by inserting config below.
17 | ```
18 | pod 'MYIntroduction', :git => 'https://github.com/MatthewYork/iPhone-IntroductionTutorial.git'
19 | ```
20 |
21 | Manual installation
22 | ========================
23 |
24 | - Add the QuartzCore framework by clicking on your Project File -> Build Phases -> Lnk Binary With Libraries
25 | - Add `MYIntroductionView.h` and `MYIntroductionView.m` to your project.
26 | - Add `MYIntroductionPanel.h` and `MYIntroductionPanel.m` to your project.
27 | - `#import "MYIntroductionView.h"` to use it in a class
28 | - Subscribe to the 'MYIntroductionDelegate' to enable delegate/callback interaction.
29 |
30 | How To Use It
31 | ========================
32 |
33 | Step 1 - Build Panels
34 | ------------------------
35 | The introduction view needs something to display, and these are done via panels. Each panel holds an image and some description text. To create a panel, simply call the `initWithImage:description:` method. Two examples may be seen below;
36 |
37 | You may initialize a panel without a title
38 | ```objc
39 | MYIntroductionPanel *panel = [[MYIntroductionPanel alloc] initWithimage:[UIImage imageNamed:@"SampleImage1"] description:@"Welcome to MYIntroductionView, your 100 percent customizable interface for introductions and tutorials! Simply add a few classes to your project, and you are ready to go!"];
40 | ```
41 |
42 | Or with a title for extra information
43 | ```objc
44 | MYIntroductionPanel *panel2 = [[MYIntroductionPanel alloc] initWithimage:[UIImage imageNamed:@"SampleImage2"] title:@"Your Ticket!" description:@"MYIntroductionView is your ticket to a great tutorial or introduction!"];
45 | ```
46 |
47 | Step 2 - Create Introduction View
48 | -----------------------
49 | Once you panels have been created, you are ready to create the introduction view. You will pass the panels you just created into this method where they will be rendered (in order) in the introduction view. An example can be found below.
50 |
51 | ```objc
52 | MYIntroductionView *introductionView = [[MYIntroductionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) headerImage:[UIImage imageNamed:@"SampleHeaderImage.png"] panels:@[panel, panel2]];
53 | ```
54 | Don't forget to set the delegate to the calling class if you are using delegation for any callbacks
55 |
56 | ```objc
57 | introductionView.delegate = self;
58 | ```
59 |
60 | *A note to those using right-to-left languages: There is another init method that includes a language direction variable. It is an enum of type `MYLanguageDirection`. If you wish to use the right-to-left mode, this is where you would instruct the view to do so.
61 |
62 | Step 3 - Show Introduction View
63 | -----------------------
64 |
65 | ```objc
66 | [introductionView showInView:self.view];
67 | ```
68 |
--------------------------------------------------------------------------------
/IntroductionExample/MYAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // MYAppDelegate.m
3 | // IntroductionExample
4 | //
5 | // Copyright (C) 2013, Matt York
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | // this software and associated documentation files (the "Software"), to deal in
9 | // the Software without restriction, including without limitation the rights to
10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | // of the Software, and to permit persons to whom the Software is furnished to do
12 | // so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in all
15 | // copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | #import "MYAppDelegate.h"
27 |
28 | #import "MYViewController.h"
29 |
30 | @implementation MYAppDelegate
31 |
32 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
33 | {
34 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
35 | // Override point for customization after application launch.
36 | self.viewController = [[MYViewController alloc] initWithNibName:@"MYViewController" bundle:nil];
37 | self.window.rootViewController = self.viewController;
38 | [self.window makeKeyAndVisible];
39 | return YES;
40 | }
41 |
42 | - (void)applicationWillResignActive:(UIApplication *)application
43 | {
44 | // 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.
45 | // 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.
46 | }
47 |
48 | - (void)applicationDidEnterBackground:(UIApplication *)application
49 | {
50 | // 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.
51 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
52 | }
53 |
54 | - (void)applicationWillEnterForeground:(UIApplication *)application
55 | {
56 | // 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.
57 | }
58 |
59 | - (void)applicationDidBecomeActive:(UIApplication *)application
60 | {
61 | // 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.
62 | }
63 |
64 | - (void)applicationWillTerminate:(UIApplication *)application
65 | {
66 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/xcuserdata/Ryan.xcuserdatad/xcschemes/IntroductionExample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/xcuserdata/shams.xcuserdatad/xcschemes/IntroductionExample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/xcuserdata/matthewyork.xcuserdatad/xcschemes/IntroductionExample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/IntroductionExample/MYIntroductionView.h:
--------------------------------------------------------------------------------
1 | //
2 | // MYIntroductionView.h
3 | // IntroductionExample
4 | //
5 | // Copyright (C) 2013, Matt York
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | // this software and associated documentation files (the "Software"), to deal in
9 | // the Software without restriction, including without limitation the rights to
10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | // of the Software, and to permit persons to whom the Software is furnished to do
12 | // so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in all
15 | // copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | #import
27 | #import "MYIntroductionPanel.h"
28 | #import
29 |
30 | typedef enum {
31 | MYFinishTypeSwipeOut = 0,
32 | MYFinishTypeSkipButton
33 | }MYFinishType;
34 |
35 | typedef enum {
36 | MYLanguageDirectionLeftToRight = 0,
37 | MYLanguageDirectionRightToLeft
38 | }MYLanguageDirection;
39 |
40 | /******************************/
41 | //Delegate Method Declarations
42 | /******************************/
43 | @protocol MYIntroductionDelegate
44 | @optional
45 | -(void)introductionDidFinishWithType:(MYFinishType)finishType;
46 | -(void)introductionDidChangeToPanel:(MYIntroductionPanel *)panel withIndex:(NSInteger)panelIndex;
47 | @end
48 |
49 |
50 | /******************************/
51 | //MYIntroductionView
52 | /******************************/
53 | @interface MYIntroductionView : UIView {
54 |
55 | //Array of panel objects passed in at initialization
56 | NSArray *Panels;
57 |
58 | //Array of views created by MYIntroductionController from MYIntroductionPanel objects. For internal use only.
59 | NSMutableArray *panelViews;
60 |
61 | //Keeps track of the index of the last panel navigated to. For internal use only.
62 | NSInteger LastPanelIndex;
63 |
64 | //Variable keeping track of language direction
65 | MYLanguageDirection LanguageDirection;
66 | }
67 |
68 |
69 | /******************************/
70 | //Properties
71 | /******************************/
72 |
73 | //Delegate
74 | @property (weak) id delegate;
75 |
76 | //Panel management
77 | @property (nonatomic, assign) NSInteger CurrentPanelIndex;
78 |
79 | //Intoduction Properties
80 | @property (nonatomic, retain) UIImageView *BackgroundImageView;
81 |
82 | //Header properties
83 | @property (nonatomic, retain) UILabel *HeaderLabel;
84 | @property (nonatomic, retain) UIImageView *HeaderImageView;
85 | @property (nonatomic, retain) UIView *HeaderView;
86 |
87 | //Content properties
88 | @property (nonatomic, retain) UIScrollView *ContentScrollView;
89 |
90 | //PageControl/Skip Button
91 | @property (nonatomic, retain) UIPageControl *PageControl;
92 | @property (nonatomic, retain) UIButton *SkipButton;
93 |
94 | //Nuts & Bolts
95 | @property BOOL device;
96 | @property BOOL device_orientation;
97 |
98 |
99 | /******************************/
100 | //Methods
101 | /******************************/
102 |
103 | //Custom Init Methods
104 | - (id)initWithFrame:(CGRect)frame headerText:(NSString *)headerText panels:(NSArray *)panels;
105 | - (id)initWithFrame:(CGRect)frame headerImage:(UIImage *)headerImage panels:(NSArray *)panels;
106 | - (id)initWithFrame:(CGRect)frame headerText:(NSString *)headerText panels:(NSArray *)panels languageDirection:(MYLanguageDirection)languageDirection;
107 | - (id)initWithFrame:(CGRect)frame headerImage:(UIImage *)headerImage panels:(NSArray *)panels languageDirection:(MYLanguageDirection)languageDirection;
108 | - (id)initWithFrame:(CGRect)frame panels:(NSArray *)panels;
109 | - (id)initWithFrame:(CGRect)frame panels:(NSArray *)panels languageDirection:(MYLanguageDirection)languageDirection;
110 |
111 | //Header Content
112 | -(void)setHeaderText:(NSString *)headerText;
113 | -(void)setHeaderImage:(UIImage *)headerImage;
114 |
115 | //Introduction Content
116 | -(void)setBackgroundImage:(UIImage *)backgroundImage;
117 | -(void)setBackgroundColor:(UIColor *)backgroundColor;
118 |
119 | //Show/Hide
120 | -(void)showInView:(UIView *)view animateDuration:(CGFloat)duration;
121 | -(void)hideWithFadeOutDuration:(CGFloat)duration;
122 |
123 |
124 | @end
125 |
--------------------------------------------------------------------------------
/IntroductionExample/MYViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // MYViewController.m
3 | // IntroductionExample
4 | //
5 | // Copyright (C) 2013, Matt York
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | // this software and associated documentation files (the "Software"), to deal in
9 | // the Software without restriction, including without limitation the rights to
10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | // of the Software, and to permit persons to whom the Software is furnished to do
12 | // so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in all
15 | // copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | #import "MYViewController.h"
27 |
28 |
29 | @interface MYViewController ()
30 |
31 | @end
32 |
33 | @implementation MYViewController
34 |
35 | - (void)viewDidLoad
36 | {
37 | [super viewDidLoad];
38 | // Do any additional setup after loading the view, typically from a nib.
39 | }
40 |
41 | -(void)viewDidAppear:(BOOL)animated{
42 |
43 | //STEP 1 Construct Panels
44 | MYIntroductionPanel *panel = [[MYIntroductionPanel alloc] initWithimage:[UIImage imageNamed:@"SampleImage1"] title:@"Sample title" description:@"Welcome to MYIntroductionView, your 100 percent customizable interface for introductions and tutorials! Simply add a few classes to your project, and you are ready to go!" ];
45 |
46 | //You may also add in a title for each panel
47 | MYIntroductionPanel *panel2 = [[MYIntroductionPanel alloc] initWithimage:[UIImage imageNamed:@"SampleImage2"] title:@"Your Ticket!" description:@"MYIntroductionView is your ticket to a great tutorial or introduction!"];
48 |
49 | //STEP 2 Create IntroductionView
50 | /*A standard version*/
51 | //MYIntroductionView *introductionView = [[MYIntroductionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) headerImage:[UIImage imageNamed:@"SampleHeaderImage.png"] panels:@[panel, panel2]];
52 |
53 | /*A version with no header (ala "Path")*/
54 | // MYIntroductionView *introductionView = [[MYIntroductionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) panels:@[panel, panel2]];
55 |
56 | /*A more customized version*/
57 | MYIntroductionView *introductionView = [[MYIntroductionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) headerText:@"MYIntroductionView" panels:@[panel, panel2] languageDirection:MYLanguageDirectionLeftToRight];
58 | [introductionView setBackgroundImage:[UIImage imageNamed:@"SampleBackground"]];
59 |
60 | /*
61 | MYIntroductionView *introductionView = [[MYIntroductionView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) headerText:@"MYIntroductionView" panels:@[panel, panel2] languageDirection:MYLanguageDirectionLeftToRight];
62 |
63 | [introductionView setBackgroundColor:[UIColor colorWithRed:37.0/255 green:104.0/255 blue:154.0/255 alpha:1.0]]; */
64 |
65 | [introductionView.BackgroundImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
66 | [introductionView.HeaderImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
67 | [introductionView.HeaderLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
68 | [introductionView.HeaderView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
69 | [introductionView.PageControl setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
70 | [introductionView.SkipButton setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
71 |
72 |
73 |
74 |
75 | //Set delegate to self for callbacks (optional)
76 | introductionView.delegate = self;
77 |
78 | //STEP 3: Show introduction view
79 | [introductionView showInView:self.view animateDuration:0.0];
80 | }
81 |
82 | - (void)didReceiveMemoryWarning
83 | {
84 | [super didReceiveMemoryWarning];
85 | // Dispose of any resources that can be recreated.
86 | }
87 |
88 | #pragma mark - Sample Delegate Methods
89 |
90 | -(void)introductionDidFinishWithType:(MYFinishType)finishType{
91 | if (finishType == MYFinishTypeSkipButton) {
92 | NSLog(@"Did Finish Introduction By Skipping It");
93 | }
94 | else if (finishType == MYFinishTypeSwipeOut){
95 | NSLog(@"Did Finish Introduction By Swiping Out");
96 | }
97 |
98 | //One might consider making the introductionview a class variable and releasing it here.
99 | // I didn't do this to keep things simple for the sake of example.
100 | }
101 |
102 | -(void)introductionDidChangeToPanel:(MYIntroductionPanel *)panel withIndex:(NSInteger)panelIndex{
103 | NSLog(@"%@ \nPanelIndex: %d", panel.Description, panelIndex);
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/xcuserdata/matthewyork.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
18 |
19 |
31 |
32 |
44 |
45 |
57 |
58 |
70 |
71 |
83 |
84 |
96 |
97 |
109 |
110 |
122 |
123 |
135 |
136 |
148 |
149 |
161 |
162 |
174 |
175 |
187 |
188 |
200 |
201 |
213 |
214 |
215 |
216 |
--------------------------------------------------------------------------------
/IntroductionExample/en.lproj/MYViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1552
5 | 12C3012
6 | 3084
7 | 1187.34
8 | 625.00
9 |
13 |
14 | IBNSLayoutConstraint
15 | IBProxyObject
16 | IBUILabel
17 | IBUIView
18 |
19 |
20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
21 |
22 |
26 |
27 |
31 |
35 |
102 |
103 |
104 |
105 |
106 |
107 | view
108 |
109 |
110 |
111 | 7
112 |
113 |
114 |
115 |
116 |
117 | 0
118 |
119 |
120 |
121 |
122 |
123 | -1
124 |
125 |
126 | File's Owner
127 |
128 |
129 | -2
130 |
131 |
132 |
133 |
134 | 6
135 |
136 |
137 |
138 |
139 |
140 | 5
141 | 0
142 |
143 | 5
144 | 1
145 |
146 | 20
147 |
148 | 1000
149 |
150 | 8
151 | 29
152 | 3
153 |
154 |
155 |
156 | 6
157 | 0
158 |
159 | 6
160 | 1
161 |
162 | 20
163 |
164 | 1000
165 |
166 | 8
167 | 29
168 | 3
169 |
170 |
171 |
172 | 3
173 | 0
174 |
175 | 3
176 | 1
177 |
178 | 57
179 |
180 | 1000
181 |
182 | 3
183 | 9
184 | 3
185 |
186 |
187 |
188 |
189 |
190 | 8
191 |
192 |
193 |
194 |
195 |
196 | 10
197 |
198 |
199 |
200 |
201 | 11
202 |
203 |
204 |
205 |
206 | 13
207 |
208 |
209 |
210 |
211 |
212 |
213 | MYViewController
214 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
215 | UIResponder
216 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
217 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
218 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
219 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
220 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
221 |
222 |
223 |
224 |
225 |
226 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
227 |
228 |
229 |
230 |
231 |
232 |
233 | 13
234 |
235 |
236 |
237 |
238 | MYViewController
239 | UIViewController
240 |
241 | IBProjectSource
242 | ./Classes/MYViewController.h
243 |
244 |
245 |
246 | NSLayoutConstraint
247 | NSObject
248 |
249 | IBProjectSource
250 | ./Classes/NSLayoutConstraint.h
251 |
252 |
253 |
254 |
255 | 0
256 | IBCocoaTouchFramework
257 | YES
258 | 3
259 | YES
260 | 2083
261 |
262 |
263 |
--------------------------------------------------------------------------------
/IntroductionExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 6C0E2DB817CE369400D18105 /* MYViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C0E2DB717CE369300D18105 /* MYViewController.m */; };
11 | F02BB21516E847B400E3D502 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F02BB21416E847B400E3D502 /* UIKit.framework */; };
12 | F02BB21716E847B400E3D502 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F02BB21616E847B400E3D502 /* Foundation.framework */; };
13 | F02BB21916E847B400E3D502 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F02BB21816E847B400E3D502 /* CoreGraphics.framework */; };
14 | F02BB21F16E847B400E3D502 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F02BB21D16E847B400E3D502 /* InfoPlist.strings */; };
15 | F02BB22116E847B400E3D502 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F02BB22016E847B400E3D502 /* main.m */; };
16 | F02BB22516E847B400E3D502 /* MYAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F02BB22416E847B400E3D502 /* MYAppDelegate.m */; };
17 | F02BB22716E847B400E3D502 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = F02BB22616E847B400E3D502 /* Default.png */; };
18 | F02BB22916E847B400E3D502 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F02BB22816E847B400E3D502 /* Default@2x.png */; };
19 | F02BB22B16E847B400E3D502 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F02BB22A16E847B400E3D502 /* Default-568h@2x.png */; };
20 | F02BB23116E847B400E3D502 /* MYViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F02BB22F16E847B400E3D502 /* MYViewController.xib */; };
21 | F02BB23916E847D600E3D502 /* MYIntroductionView.m in Sources */ = {isa = PBXBuildFile; fileRef = F02BB23816E847D600E3D502 /* MYIntroductionView.m */; };
22 | F02BB24116E8576100E3D502 /* MYIntroductionPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = F02BB24016E8576100E3D502 /* MYIntroductionPanel.m */; };
23 | F02BB24816E961B300E3D502 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F02BB24716E961B300E3D502 /* QuartzCore.framework */; };
24 | F02BB25A16E9991F00E3D502 /* SampleHeaderImage.png in Resources */ = {isa = PBXBuildFile; fileRef = F02BB25916E9991F00E3D502 /* SampleHeaderImage.png */; };
25 | F02BB26816E9A67C00E3D502 /* SampleBackground.png in Resources */ = {isa = PBXBuildFile; fileRef = F02BB26716E9A67C00E3D502 /* SampleBackground.png */; };
26 | F0558C4716EEBEF100B8BFA3 /* SampleImage1.png in Resources */ = {isa = PBXBuildFile; fileRef = F0558C4616EEBEF100B8BFA3 /* SampleImage1.png */; };
27 | F0558C4916EEC0D400B8BFA3 /* SampleImage2.png in Resources */ = {isa = PBXBuildFile; fileRef = F0558C4816EEC0D400B8BFA3 /* SampleImage2.png */; };
28 | /* End PBXBuildFile section */
29 |
30 | /* Begin PBXFileReference section */
31 | 6C0E2DB717CE369300D18105 /* MYViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYViewController.m; sourceTree = ""; };
32 | F02BB21116E847B400E3D502 /* IntroductionExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IntroductionExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
33 | F02BB21416E847B400E3D502 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
34 | F02BB21616E847B400E3D502 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
35 | F02BB21816E847B400E3D502 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
36 | F02BB21C16E847B400E3D502 /* IntroductionExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "IntroductionExample-Info.plist"; sourceTree = ""; };
37 | F02BB21E16E847B400E3D502 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
38 | F02BB22016E847B400E3D502 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
39 | F02BB22216E847B400E3D502 /* IntroductionExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "IntroductionExample-Prefix.pch"; sourceTree = ""; };
40 | F02BB22316E847B400E3D502 /* MYAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MYAppDelegate.h; sourceTree = ""; };
41 | F02BB22416E847B400E3D502 /* MYAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MYAppDelegate.m; sourceTree = ""; };
42 | F02BB22616E847B400E3D502 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; };
43 | F02BB22816E847B400E3D502 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; };
44 | F02BB22A16E847B400E3D502 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
45 | F02BB22C16E847B400E3D502 /* MYViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MYViewController.h; sourceTree = ""; };
46 | F02BB23016E847B400E3D502 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MYViewController.xib; sourceTree = ""; };
47 | F02BB23716E847D600E3D502 /* MYIntroductionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYIntroductionView.h; sourceTree = ""; };
48 | F02BB23816E847D600E3D502 /* MYIntroductionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYIntroductionView.m; sourceTree = ""; };
49 | F02BB23F16E8576100E3D502 /* MYIntroductionPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MYIntroductionPanel.h; sourceTree = ""; };
50 | F02BB24016E8576100E3D502 /* MYIntroductionPanel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYIntroductionPanel.m; sourceTree = ""; };
51 | F02BB24716E961B300E3D502 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
52 | F02BB25916E9991F00E3D502 /* SampleHeaderImage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SampleHeaderImage.png; sourceTree = ""; };
53 | F02BB26716E9A67C00E3D502 /* SampleBackground.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SampleBackground.png; sourceTree = ""; };
54 | F0558C4616EEBEF100B8BFA3 /* SampleImage1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SampleImage1.png; sourceTree = ""; };
55 | F0558C4816EEC0D400B8BFA3 /* SampleImage2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SampleImage2.png; sourceTree = ""; };
56 | /* End PBXFileReference section */
57 |
58 | /* Begin PBXFrameworksBuildPhase section */
59 | F02BB20E16E847B400E3D502 /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | F02BB24816E961B300E3D502 /* QuartzCore.framework in Frameworks */,
64 | F02BB21516E847B400E3D502 /* UIKit.framework in Frameworks */,
65 | F02BB21716E847B400E3D502 /* Foundation.framework in Frameworks */,
66 | F02BB21916E847B400E3D502 /* CoreGraphics.framework in Frameworks */,
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | /* End PBXFrameworksBuildPhase section */
71 |
72 | /* Begin PBXGroup section */
73 | F02BB20816E847B400E3D502 = {
74 | isa = PBXGroup;
75 | children = (
76 | F02BB21A16E847B400E3D502 /* IntroductionExample */,
77 | F02BB21316E847B400E3D502 /* Frameworks */,
78 | F02BB21216E847B400E3D502 /* Products */,
79 | );
80 | sourceTree = "";
81 | };
82 | F02BB21216E847B400E3D502 /* Products */ = {
83 | isa = PBXGroup;
84 | children = (
85 | F02BB21116E847B400E3D502 /* IntroductionExample.app */,
86 | );
87 | name = Products;
88 | sourceTree = "";
89 | };
90 | F02BB21316E847B400E3D502 /* Frameworks */ = {
91 | isa = PBXGroup;
92 | children = (
93 | F02BB24716E961B300E3D502 /* QuartzCore.framework */,
94 | F02BB21416E847B400E3D502 /* UIKit.framework */,
95 | F02BB21616E847B400E3D502 /* Foundation.framework */,
96 | F02BB21816E847B400E3D502 /* CoreGraphics.framework */,
97 | );
98 | name = Frameworks;
99 | sourceTree = "";
100 | };
101 | F02BB21A16E847B400E3D502 /* IntroductionExample */ = {
102 | isa = PBXGroup;
103 | children = (
104 | F02BB22316E847B400E3D502 /* MYAppDelegate.h */,
105 | F02BB22416E847B400E3D502 /* MYAppDelegate.m */,
106 | F02BB22C16E847B400E3D502 /* MYViewController.h */,
107 | 6C0E2DB717CE369300D18105 /* MYViewController.m */,
108 | F02BB22F16E847B400E3D502 /* MYViewController.xib */,
109 | F02BB24216E90F6A00E3D502 /* MYIntroductionView */,
110 | F02BB21B16E847B400E3D502 /* Supporting Files */,
111 | );
112 | path = IntroductionExample;
113 | sourceTree = "";
114 | };
115 | F02BB21B16E847B400E3D502 /* Supporting Files */ = {
116 | isa = PBXGroup;
117 | children = (
118 | F0558C4616EEBEF100B8BFA3 /* SampleImage1.png */,
119 | F0558C4816EEC0D400B8BFA3 /* SampleImage2.png */,
120 | F02BB25916E9991F00E3D502 /* SampleHeaderImage.png */,
121 | F02BB26716E9A67C00E3D502 /* SampleBackground.png */,
122 | F02BB21C16E847B400E3D502 /* IntroductionExample-Info.plist */,
123 | F02BB21D16E847B400E3D502 /* InfoPlist.strings */,
124 | F02BB22016E847B400E3D502 /* main.m */,
125 | F02BB22216E847B400E3D502 /* IntroductionExample-Prefix.pch */,
126 | F02BB22616E847B400E3D502 /* Default.png */,
127 | F02BB22816E847B400E3D502 /* Default@2x.png */,
128 | F02BB22A16E847B400E3D502 /* Default-568h@2x.png */,
129 | );
130 | name = "Supporting Files";
131 | sourceTree = "";
132 | };
133 | F02BB24216E90F6A00E3D502 /* MYIntroductionView */ = {
134 | isa = PBXGroup;
135 | children = (
136 | F02BB23716E847D600E3D502 /* MYIntroductionView.h */,
137 | F02BB23816E847D600E3D502 /* MYIntroductionView.m */,
138 | F02BB23F16E8576100E3D502 /* MYIntroductionPanel.h */,
139 | F02BB24016E8576100E3D502 /* MYIntroductionPanel.m */,
140 | );
141 | name = MYIntroductionView;
142 | sourceTree = "";
143 | };
144 | /* End PBXGroup section */
145 |
146 | /* Begin PBXNativeTarget section */
147 | F02BB21016E847B400E3D502 /* IntroductionExample */ = {
148 | isa = PBXNativeTarget;
149 | buildConfigurationList = F02BB23416E847B400E3D502 /* Build configuration list for PBXNativeTarget "IntroductionExample" */;
150 | buildPhases = (
151 | F02BB20D16E847B400E3D502 /* Sources */,
152 | F02BB20E16E847B400E3D502 /* Frameworks */,
153 | F02BB20F16E847B400E3D502 /* Resources */,
154 | );
155 | buildRules = (
156 | );
157 | dependencies = (
158 | );
159 | name = IntroductionExample;
160 | productName = IntroductionExample;
161 | productReference = F02BB21116E847B400E3D502 /* IntroductionExample.app */;
162 | productType = "com.apple.product-type.application";
163 | };
164 | /* End PBXNativeTarget section */
165 |
166 | /* Begin PBXProject section */
167 | F02BB20916E847B400E3D502 /* Project object */ = {
168 | isa = PBXProject;
169 | attributes = {
170 | CLASSPREFIX = MY;
171 | LastUpgradeCheck = 0460;
172 | ORGANIZATIONNAME = "Matthew York";
173 | };
174 | buildConfigurationList = F02BB20C16E847B400E3D502 /* Build configuration list for PBXProject "IntroductionExample" */;
175 | compatibilityVersion = "Xcode 3.2";
176 | developmentRegion = English;
177 | hasScannedForEncodings = 0;
178 | knownRegions = (
179 | en,
180 | );
181 | mainGroup = F02BB20816E847B400E3D502;
182 | productRefGroup = F02BB21216E847B400E3D502 /* Products */;
183 | projectDirPath = "";
184 | projectRoot = "";
185 | targets = (
186 | F02BB21016E847B400E3D502 /* IntroductionExample */,
187 | );
188 | };
189 | /* End PBXProject section */
190 |
191 | /* Begin PBXResourcesBuildPhase section */
192 | F02BB20F16E847B400E3D502 /* Resources */ = {
193 | isa = PBXResourcesBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | F02BB21F16E847B400E3D502 /* InfoPlist.strings in Resources */,
197 | F02BB22716E847B400E3D502 /* Default.png in Resources */,
198 | F02BB22916E847B400E3D502 /* Default@2x.png in Resources */,
199 | F02BB22B16E847B400E3D502 /* Default-568h@2x.png in Resources */,
200 | F02BB23116E847B400E3D502 /* MYViewController.xib in Resources */,
201 | F02BB25A16E9991F00E3D502 /* SampleHeaderImage.png in Resources */,
202 | F02BB26816E9A67C00E3D502 /* SampleBackground.png in Resources */,
203 | F0558C4716EEBEF100B8BFA3 /* SampleImage1.png in Resources */,
204 | F0558C4916EEC0D400B8BFA3 /* SampleImage2.png in Resources */,
205 | );
206 | runOnlyForDeploymentPostprocessing = 0;
207 | };
208 | /* End PBXResourcesBuildPhase section */
209 |
210 | /* Begin PBXSourcesBuildPhase section */
211 | F02BB20D16E847B400E3D502 /* Sources */ = {
212 | isa = PBXSourcesBuildPhase;
213 | buildActionMask = 2147483647;
214 | files = (
215 | F02BB22116E847B400E3D502 /* main.m in Sources */,
216 | F02BB22516E847B400E3D502 /* MYAppDelegate.m in Sources */,
217 | F02BB23916E847D600E3D502 /* MYIntroductionView.m in Sources */,
218 | F02BB24116E8576100E3D502 /* MYIntroductionPanel.m in Sources */,
219 | 6C0E2DB817CE369400D18105 /* MYViewController.m in Sources */,
220 | );
221 | runOnlyForDeploymentPostprocessing = 0;
222 | };
223 | /* End PBXSourcesBuildPhase section */
224 |
225 | /* Begin PBXVariantGroup section */
226 | F02BB21D16E847B400E3D502 /* InfoPlist.strings */ = {
227 | isa = PBXVariantGroup;
228 | children = (
229 | F02BB21E16E847B400E3D502 /* en */,
230 | );
231 | name = InfoPlist.strings;
232 | sourceTree = "";
233 | };
234 | F02BB22F16E847B400E3D502 /* MYViewController.xib */ = {
235 | isa = PBXVariantGroup;
236 | children = (
237 | F02BB23016E847B400E3D502 /* en */,
238 | );
239 | name = MYViewController.xib;
240 | sourceTree = "";
241 | };
242 | /* End PBXVariantGroup section */
243 |
244 | /* Begin XCBuildConfiguration section */
245 | F02BB23216E847B400E3D502 /* Debug */ = {
246 | isa = XCBuildConfiguration;
247 | buildSettings = {
248 | ALWAYS_SEARCH_USER_PATHS = NO;
249 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
250 | CLANG_CXX_LIBRARY = "libc++";
251 | CLANG_ENABLE_OBJC_ARC = YES;
252 | CLANG_WARN_CONSTANT_CONVERSION = YES;
253 | CLANG_WARN_EMPTY_BODY = YES;
254 | CLANG_WARN_ENUM_CONVERSION = YES;
255 | CLANG_WARN_INT_CONVERSION = YES;
256 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
257 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
258 | COPY_PHASE_STRIP = NO;
259 | GCC_C_LANGUAGE_STANDARD = gnu99;
260 | GCC_DYNAMIC_NO_PIC = NO;
261 | GCC_OPTIMIZATION_LEVEL = 0;
262 | GCC_PREPROCESSOR_DEFINITIONS = (
263 | "DEBUG=1",
264 | "$(inherited)",
265 | );
266 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
267 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
268 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
269 | GCC_WARN_UNUSED_VARIABLE = YES;
270 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
271 | ONLY_ACTIVE_ARCH = YES;
272 | SDKROOT = iphoneos;
273 | };
274 | name = Debug;
275 | };
276 | F02BB23316E847B400E3D502 /* Release */ = {
277 | isa = XCBuildConfiguration;
278 | buildSettings = {
279 | ALWAYS_SEARCH_USER_PATHS = NO;
280 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
281 | CLANG_CXX_LIBRARY = "libc++";
282 | CLANG_ENABLE_OBJC_ARC = YES;
283 | CLANG_WARN_CONSTANT_CONVERSION = YES;
284 | CLANG_WARN_EMPTY_BODY = YES;
285 | CLANG_WARN_ENUM_CONVERSION = YES;
286 | CLANG_WARN_INT_CONVERSION = YES;
287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
288 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
289 | COPY_PHASE_STRIP = YES;
290 | GCC_C_LANGUAGE_STANDARD = gnu99;
291 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
292 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
293 | GCC_WARN_UNUSED_VARIABLE = YES;
294 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
295 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
296 | SDKROOT = iphoneos;
297 | VALIDATE_PRODUCT = YES;
298 | };
299 | name = Release;
300 | };
301 | F02BB23516E847B400E3D502 /* Debug */ = {
302 | isa = XCBuildConfiguration;
303 | buildSettings = {
304 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
305 | GCC_PREFIX_HEADER = "IntroductionExample/IntroductionExample-Prefix.pch";
306 | INFOPLIST_FILE = "IntroductionExample/IntroductionExample-Info.plist";
307 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
308 | PRODUCT_NAME = "$(TARGET_NAME)";
309 | TARGETED_DEVICE_FAMILY = "1,2";
310 | WRAPPER_EXTENSION = app;
311 | };
312 | name = Debug;
313 | };
314 | F02BB23616E847B400E3D502 /* Release */ = {
315 | isa = XCBuildConfiguration;
316 | buildSettings = {
317 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
318 | GCC_PREFIX_HEADER = "IntroductionExample/IntroductionExample-Prefix.pch";
319 | INFOPLIST_FILE = "IntroductionExample/IntroductionExample-Info.plist";
320 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
321 | PRODUCT_NAME = "$(TARGET_NAME)";
322 | TARGETED_DEVICE_FAMILY = "1,2";
323 | WRAPPER_EXTENSION = app;
324 | };
325 | name = Release;
326 | };
327 | /* End XCBuildConfiguration section */
328 |
329 | /* Begin XCConfigurationList section */
330 | F02BB20C16E847B400E3D502 /* Build configuration list for PBXProject "IntroductionExample" */ = {
331 | isa = XCConfigurationList;
332 | buildConfigurations = (
333 | F02BB23216E847B400E3D502 /* Debug */,
334 | F02BB23316E847B400E3D502 /* Release */,
335 | );
336 | defaultConfigurationIsVisible = 0;
337 | defaultConfigurationName = Release;
338 | };
339 | F02BB23416E847B400E3D502 /* Build configuration list for PBXNativeTarget "IntroductionExample" */ = {
340 | isa = XCConfigurationList;
341 | buildConfigurations = (
342 | F02BB23516E847B400E3D502 /* Debug */,
343 | F02BB23616E847B400E3D502 /* Release */,
344 | );
345 | defaultConfigurationIsVisible = 0;
346 | defaultConfigurationName = Release;
347 | };
348 | /* End XCConfigurationList section */
349 | };
350 | rootObject = F02BB20916E847B400E3D502 /* Project object */;
351 | }
352 |
--------------------------------------------------------------------------------
/IntroductionExample/MYIntroductionView.m:
--------------------------------------------------------------------------------
1 | //
2 | // MYIntroductionView.m
3 | // IntroductionExample
4 | //
5 | // Copyright (C) 2013, Matt York
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 | // this software and associated documentation files (the "Software"), to deal in
9 | // the Software without restriction, including without limitation the rights to
10 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11 | // of the Software, and to permit persons to whom the Software is furnished to do
12 | // so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in all
15 | // copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | // SOFTWARE.
24 | //
25 |
26 | #import "MYIntroductionView.h"
27 |
28 | #define DEFAULT_BACKGROUND_COLOR [UIColor colorWithWhite:0 alpha:0.9]
29 | #define HEADER_VIEW_HEIGHT 45
30 | #define PAGE_CONTROL_PADDING 1
31 | #define TITLE_FONT [UIFont fontWithName:@"HelveticaNeue-Bold" size:16.0]
32 | #define TITLE_TEXT_COLOR [UIColor whiteColor]
33 | #define DESCRIPTION_FONT [UIFont fontWithName:@"HelveticaNeue-Light" size:13.0]
34 | #define DESCRIPTION_TEXT_COLOR [UIColor whiteColor]
35 |
36 | @implementation MYIntroductionView
37 | @synthesize delegate, device, device_orientation;
38 |
39 | - (id)initWithFrame:(CGRect)frame
40 | {
41 | self = [super initWithFrame:frame];
42 | if (self) {
43 | // Initialization code
44 | [self initializeClassVariables];
45 | [self buildUIWithFrame:frame headerViewVisible:YES];
46 | [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
47 | }
48 | return self;
49 | }
50 |
51 | - (id)initWithFrame:(CGRect)frame headerText:(NSString *)headerText panels:(NSArray *)panels
52 | {
53 | self = [super initWithFrame:frame];
54 | if (self) {
55 | // Initialization code
56 | [self initializeClassVariables];
57 | Panels = [panels copy];
58 | LanguageDirection = MYLanguageDirectionLeftToRight;
59 | [self buildUIWithFrame:frame headerViewVisible:YES];
60 | [self setHeaderText:headerText];
61 | [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
62 | }
63 | return self;
64 | }
65 |
66 | - (id)initWithFrame:(CGRect)frame headerImage:(UIImage *)headerImage panels:(NSArray *)panels
67 | {
68 | self = [super initWithFrame:frame];
69 | if (self) {
70 | // Initialization code
71 | [self initializeClassVariables];
72 | Panels = [panels copy];
73 | LanguageDirection = MYLanguageDirectionLeftToRight;
74 | [self buildUIWithFrame:frame headerViewVisible:YES];
75 | [self setHeaderImage:headerImage];
76 | [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
77 | }
78 | return self;
79 | }
80 |
81 | - (id)initWithFrame:(CGRect)frame headerText:(NSString *)headerText panels:(NSArray *)panels languageDirection:(MYLanguageDirection)languageDirection
82 | {
83 | self = [super initWithFrame:frame];
84 | if (self) {
85 | // Initialization code
86 | [self initializeClassVariables];
87 | Panels = [panels copy];
88 | LanguageDirection = languageDirection;
89 | [self buildUIWithFrame:frame headerViewVisible:YES];
90 | [self setHeaderText:headerText];
91 | [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
92 | }
93 | return self;
94 | }
95 |
96 | - (id)initWithFrame:(CGRect)frame headerImage:(UIImage *)headerImage panels:(NSArray *)panels languageDirection:(MYLanguageDirection)languageDirection
97 | {
98 | self = [super initWithFrame:frame];
99 | if (self) {
100 | // Initialization code
101 | [self initializeClassVariables];
102 | Panels = [panels copy];
103 | LanguageDirection = languageDirection;
104 | [self buildUIWithFrame:frame headerViewVisible:YES];
105 | [self setHeaderImage:headerImage];
106 | [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
107 | }
108 | return self;
109 | }
110 |
111 | - (id)initWithFrame:(CGRect)frame panels:(NSArray *)panels
112 | {
113 | self = [super initWithFrame:frame];
114 | if (self) {
115 | // Initialization code
116 | [self initializeClassVariables];
117 | Panels = [panels copy];
118 | LanguageDirection = MYLanguageDirectionLeftToRight;
119 | [self buildUIWithFrame:frame headerViewVisible:NO];
120 | [self setHeaderText:nil];
121 | }
122 | return self;
123 | }
124 |
125 | - (id)initWithFrame:(CGRect)frame panels:(NSArray *)panels languageDirection:(MYLanguageDirection)languageDirection
126 | {
127 | self = [super initWithFrame:frame];
128 | if (self) {
129 | // Initialization code
130 | [self initializeClassVariables];
131 | Panels = [panels copy];
132 | LanguageDirection = languageDirection;
133 | [self buildUIWithFrame:frame headerViewVisible:NO];
134 | [self setHeaderText:nil];
135 | [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
136 | }
137 | return self;
138 | }
139 |
140 |
141 | -(void)initializeClassVariables{
142 | panelViews = [[NSMutableArray alloc] init];
143 | self.device = [self getCurrentDevice];
144 | self.device_orientation = [self getCurrentOrientation];
145 | }
146 |
147 | #pragma mark - UI Builder Methods
148 |
149 | -(BOOL)getCurrentDevice {
150 | return [[UIDevice currentDevice] userInterfaceIdiom]; //iPhone 1; iPad 0;
151 | }
152 |
153 | -(BOOL)getCurrentOrientation {
154 | switch ([[UIApplication sharedApplication] statusBarOrientation]) {
155 | case UIInterfaceOrientationPortrait:
156 | return 0;
157 | break;
158 | case UIInterfaceOrientationPortraitUpsideDown:
159 | return 0;
160 | break;
161 | case UIInterfaceOrientationLandscapeLeft:
162 | return 1;
163 | break;
164 | case UIInterfaceOrientationLandscapeRight:
165 | return 1;
166 | break;
167 | default:
168 | return 0;
169 | break;
170 | }
171 | }
172 |
173 | -(void)buildUIWithFrame:(CGRect)frame headerViewVisible:(BOOL)headerViewVisible{
174 | self.backgroundColor = DEFAULT_BACKGROUND_COLOR;
175 |
176 | [self buildBackgroundImage];
177 | [self buildHeaderViewWithFrame:frame visible:headerViewVisible];
178 | [self buildContentScrollViewWithFrame:frame];
179 | [self buildFooterView];
180 |
181 | [self.BackgroundImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
182 | [self.HeaderImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
183 | [self.HeaderLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
184 | [self.HeaderView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
185 | [self.PageControl setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
186 | [self.SkipButton setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
187 | }
188 |
189 | -(void)buildBackgroundImage{
190 | self.BackgroundImageView = [[UIImageView alloc] initWithFrame:self.frame];
191 | self.BackgroundImageView.backgroundColor = [UIColor clearColor];
192 | self.BackgroundImageView.contentMode = UIViewContentModeScaleToFill;
193 | self.BackgroundImageView.autoresizesSubviews = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
194 | [self addSubview:self.BackgroundImageView];
195 | }
196 |
197 | -(void)buildHeaderViewWithFrame:(CGRect)frame visible:(BOOL)visible{
198 | if (!visible) {
199 | self.HeaderView = [[UIView alloc] initWithFrame:CGRectZero];
200 | return;
201 | }
202 |
203 | float headerYOffset = 5;
204 | if ([MYIntroductionView runningiOS7]) {
205 | headerYOffset = headerYOffset + 20;
206 | }
207 |
208 | self.HeaderView = [[UIView alloc] initWithFrame:CGRectMake(5, headerYOffset, frame.size.width - 10, HEADER_VIEW_HEIGHT)]; //Leave 5px padding on all sides
209 | self.HeaderView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
210 | self.HeaderView.backgroundColor = [UIColor clearColor];
211 |
212 | //Setup HeaderImageView
213 | self.HeaderImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.HeaderView.frame.size.width, self.HeaderView.frame.size.height)];
214 | self.HeaderImageView.backgroundColor = [UIColor clearColor];
215 | self.HeaderImageView.contentMode = UIViewContentModeScaleAspectFit;
216 | self.HeaderImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
217 | [self.HeaderView addSubview:self.HeaderImageView];
218 | self.HeaderImageView.hidden = YES;
219 |
220 | //Setup HeaderLabel
221 | self.HeaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.HeaderView.frame.size.width, self.HeaderView.frame.size.height)];
222 | self.HeaderLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:25.0];
223 | self.HeaderLabel.textColor = [UIColor whiteColor];
224 | self.HeaderLabel.backgroundColor = [UIColor clearColor];
225 | self.HeaderLabel.textAlignment = NSTextAlignmentCenter;
226 | self.HeaderLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
227 | [self.HeaderView addSubview:self.HeaderLabel];
228 | self.HeaderLabel.hidden = YES;
229 | [self addSubview:self.HeaderView];
230 |
231 | // Add a drop shadow to the header text
232 | /*
233 | self.HeaderLabel.layer.shadowColor = [[UIColor blackColor]CGColor];
234 | self.HeaderLabel.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
235 | self.HeaderLabel.layer.shadowOpacity = 1.0f;
236 | self.HeaderLabel.layer.shadowRadius = 1.0f;
237 | */
238 | }
239 |
240 | -(void)buildContentScrollViewWithFrame:(CGRect)frame{
241 | float centerPadding = frame.size.width;
242 | float outerPadding = 0;
243 | if (self.device == 0) { // iPhone
244 | if (self.device_orientation == 1) { // 1 for landscape
245 | self.ContentScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, self.HeaderView.frame.origin.y + self.HeaderView.frame.size.height - HEADER_VIEW_HEIGHT, frame.size.width, 0)];
246 | } else {
247 | self.ContentScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, self.HeaderView.frame.origin.y + self.HeaderView.frame.size.height, frame.size.width, 0)];
248 | }
249 | } else { // iPad
250 | if (self.device_orientation == 1) { // 1 for landscape
251 | centerPadding = self.frame.size.height;
252 | outerPadding = (self.frame.size.width - self.frame.size.height)/2;
253 | NSLog(@"C:%f, O:%f", centerPadding, outerPadding);
254 | }
255 | self.ContentScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(outerPadding, self.HeaderView.frame.origin.y + self.HeaderView.frame.size.height + 10, centerPadding, 0)];
256 | }
257 |
258 | self.ContentScrollView.pagingEnabled = YES;
259 | self.ContentScrollView.showsHorizontalScrollIndicator = NO;
260 | self.ContentScrollView.showsVerticalScrollIndicator = NO;
261 | self.ContentScrollView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
262 | self.ContentScrollView.delegate = self;
263 |
264 | //If panels exist, build views for them and add them to the ContentScrollView
265 | if (Panels) {
266 | if (Panels.count > 0) {
267 | if (LanguageDirection == MYLanguageDirectionLeftToRight) {
268 | [self buildContentScrollViewLeftToRight];
269 | }
270 | else if (LanguageDirection == MYLanguageDirectionRightToLeft) {
271 | [self buildContentScrollViewRightToLeft];
272 | }
273 | }
274 | }
275 | }
276 |
277 |
278 | -(void)buildContentScrollViewLeftToRight{
279 | //A running x-coordinate. This grows for every page
280 | CGFloat contentXIndex = 0;
281 | for (int ii = 0; ii < Panels.count; ii++) {
282 |
283 | //Create a new view for the panel and add it to the array
284 | [panelViews addObject:[self PanelViewForPanel:Panels[ii] atXIndex:&contentXIndex]];
285 |
286 | //Add the newly created panel view to ContentScrollView
287 | [self.ContentScrollView addSubview:panelViews[ii]];
288 | }
289 |
290 |
291 | [self makePanelVisibleAtIndex:0];
292 |
293 | //Dynamically sizes the content to fit the text content
294 | [self setContentScrollViewHeightForPanelIndex:0 animated:NO];
295 |
296 | //Add a view at the end. This is simply "something to scroll toward" on the final panel.
297 | [self appendCloseViewAtXIndex:&contentXIndex];
298 |
299 | //Finally, resize the content size of the scrollview to account for all the new views added to it
300 | self.ContentScrollView.contentSize = CGSizeMake(contentXIndex, self.ContentScrollView.frame.size.height);
301 |
302 | //Add the ContentScrollView to the introduction view
303 | [self addSubview:self.ContentScrollView];
304 | }
305 |
306 | -(void)buildContentScrollViewRightToLeft{
307 | //A running x-coordinate. This grows for every page
308 | CGFloat contentXIndex = 0;
309 |
310 | //Add a view at the end. This is simply "something to scroll toward" on the final panel.
311 | [self appendCloseViewAtXIndex:&contentXIndex];
312 |
313 | NSInteger panelViewIndex = 0;
314 | for (int ii = Panels.count-1; ii > -1; ii--) {
315 |
316 | //Create a new view for the panel and add it to the array
317 | [panelViews addObject:[self PanelViewForPanel:Panels[ii] atXIndex:&contentXIndex]];
318 |
319 | //Add the newly created panel view to ContentScrollView
320 | [self.ContentScrollView addSubview:panelViews[panelViewIndex]];
321 | panelViewIndex++;
322 | }
323 |
324 | [self makePanelVisibleAtIndex:panelViews.count-1];
325 | self.CurrentPanelIndex = panelViews.count-1;
326 | self.PageControl.currentPage = panelViews.count -1;
327 |
328 | //Dynamically sizes the content to fit the text content
329 | [self setContentScrollViewHeightForPanelIndex:Panels.count-1 animated:NO];
330 |
331 | //Finally, resize the content size of the scrollview to account for all the new views added to it
332 | self.ContentScrollView.contentSize = CGSizeMake(contentXIndex, self.ContentScrollView.frame.size.height);
333 | self.ContentScrollView.contentOffset = CGPointMake(contentXIndex-self.ContentScrollView.frame.size.width, 0);
334 |
335 | //Add the ContentScrollView to the introduction view
336 | [self addSubview:self.ContentScrollView];
337 | }
338 |
339 | -(UIView *)PanelViewForPanel:(MYIntroductionPanel *)panel atXIndex:(CGFloat*)xIndex{
340 |
341 | //Build panel now that we have all the desired dimensions
342 | UIView *panelView = [[UIView alloc] initWithFrame:CGRectMake(*xIndex, 0, self.ContentScrollView.frame.size.width, 0)];
343 |
344 | CGFloat imageHeight = MIN(panel.Image.size.height, self.frame.size.width - 10);
345 |
346 | //Build title container (if applicable)
347 | CGRect panelTitleLabelFrame;
348 | UILabel *panelTitleLabel;
349 | if (![panel.Title isEqualToString:@""]) {
350 | panelTitleLabelFrame = CGRectMake(10, imageHeight+5, self.ContentScrollView.frame.size.width - 20, [panel.Title sizeWithFont:TITLE_FONT constrainedToSize:CGSizeMake(self.ContentScrollView.frame.size.width - 20, 100) lineBreakMode:NSLineBreakByWordWrapping].height);
351 | panelTitleLabel = [[UILabel alloc] initWithFrame:panelTitleLabelFrame];
352 | panelTitleLabel.text = panel.Title;
353 | panelTitleLabel.font = TITLE_FONT;
354 | panelTitleLabel.textColor = TITLE_TEXT_COLOR;
355 | panelTitleLabel.backgroundColor = [UIColor clearColor];
356 | panelTitleLabel.textAlignment = NSTextAlignmentCenter;
357 | panelTitleLabel.lineBreakMode = NSLineBreakByWordWrapping;
358 | // Add a drop shadow to the title text
359 | /*
360 | panelTitleLabel.layer.shadowColor = [[UIColor blackColor]CGColor];
361 | panelTitleLabel.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
362 | panelTitleLabel.layer.shadowOpacity = 1.0f;
363 | panelTitleLabel.layer.shadowRadius = 1.0f;
364 | */
365 | }
366 | else {
367 | panelTitleLabelFrame = CGRectMake(10, imageHeight+5, self.ContentScrollView.frame.size.width - 20, 0);
368 | panelTitleLabel = [[UILabel alloc] initWithFrame:panelTitleLabelFrame];
369 | }
370 | [panelView addSubview:panelTitleLabel];
371 |
372 | //Build description container;
373 | UITextView *panelDescriptionTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, self.ContentScrollView.frame.size.width, 0)];
374 | panelDescriptionTextView.scrollEnabled = NO;
375 | panelDescriptionTextView.backgroundColor = [UIColor clearColor];
376 | panelDescriptionTextView.textAlignment = NSTextAlignmentCenter;
377 | panelDescriptionTextView.textColor = DESCRIPTION_TEXT_COLOR;
378 | panelDescriptionTextView.font = DESCRIPTION_FONT;
379 | panelDescriptionTextView.text = panel.Description;
380 | panelDescriptionTextView.editable = NO;
381 | [panelDescriptionTextView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin];
382 | [panelDescriptionTextView sizeToFit];
383 | [panelView addSubview:panelDescriptionTextView];
384 |
385 | // Add a drop shadow to the description text
386 | /*
387 | panelDescriptionTextView.userInteractionEnabled = false;
388 | panelDescriptionTextView.layer.shadowColor = [[UIColor blackColor]CGColor];
389 | panelDescriptionTextView.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
390 | panelDescriptionTextView.layer.shadowOpacity = 1.0f;
391 | panelDescriptionTextView.layer.shadowRadius = 1.0f;
392 | */
393 |
394 | //Gather a few layout parameters
395 | //Get the maximum size the description text could be (screenHeight-panelParentContainerOrigin - footersize)
396 |
397 | CGFloat maxScrollViewHeight = self.frame.size.height - self.ContentScrollView.frame.origin.y - (36+PAGE_CONTROL_PADDING);
398 |
399 |
400 | NSInteger descriptionHeight = panelDescriptionTextView.contentSize.height;
401 |
402 | if ([MYIntroductionView runningiOS7]) {
403 | descriptionHeight = panelDescriptionTextView.frame.size.height;
404 | }
405 | int contentWrappedScrollViewHeight = 0;
406 | if ((imageHeight + descriptionHeight + panelTitleLabelFrame.size.height) > maxScrollViewHeight) {
407 | contentWrappedScrollViewHeight = maxScrollViewHeight;
408 | imageHeight = contentWrappedScrollViewHeight-descriptionHeight - panelTitleLabelFrame.size.height - 10;
409 | }
410 | else if ((imageHeight+descriptionHeight + panelTitleLabelFrame.size.height) <= maxScrollViewHeight){
411 | contentWrappedScrollViewHeight = imageHeight + panelTitleLabelFrame.size.height + descriptionHeight;
412 | }
413 |
414 | panelView.frame = CGRectMake(*xIndex, 0, self.ContentScrollView.frame.size.width, contentWrappedScrollViewHeight);
415 |
416 | //Build image container
417 | UIImageView *panelImageView = [[UIImageView alloc] initWithFrame:CGRectMake(5, 0, self.ContentScrollView.frame.size.width - 10, imageHeight)];
418 | panelImageView.contentMode = UIViewContentModeScaleAspectFit;
419 | panelImageView.backgroundColor = [UIColor clearColor];
420 | panelImageView.image = panel.Image;
421 | panelImageView.layer.cornerRadius = 3;
422 | panelImageView.clipsToBounds = YES;
423 | [panelView addSubview:panelImageView];
424 |
425 |
426 | //Update frames based on the new/scaled image size we just gathered
427 | panelTitleLabel.frame = CGRectMake(10, imageHeight + 5, panelTitleLabel.frame.size.width, panelTitleLabel.frame.size.height);
428 | panelDescriptionTextView.frame = CGRectMake(0, imageHeight + panelTitleLabel.frame.size.height + 5, self.ContentScrollView.frame.size.width, descriptionHeight);
429 |
430 | //Update xIndex
431 | *xIndex += self.ContentScrollView.frame.size.width;
432 |
433 | return panelView;
434 | }
435 |
436 | -(void)appendCloseViewAtXIndex:(CGFloat*)xIndex{
437 | UIView *closeView = [[UIView alloc] initWithFrame:CGRectMake(*xIndex, 0, self.frame.size.width, 400)];
438 |
439 | [self.ContentScrollView addSubview:closeView];
440 |
441 | *xIndex += self.ContentScrollView.frame.size.width;
442 | }
443 |
444 | -(void)showPanelAtPageControl {
445 |
446 | LastPanelIndex = self.PageControl.currentPage;
447 | self.CurrentPanelIndex = self.PageControl.currentPage;
448 |
449 | //Format and show new content
450 | [self setContentScrollViewHeightForPanelIndex:self.CurrentPanelIndex animated:YES];
451 | [self makePanelVisibleAtIndex:(NSInteger)self.CurrentPanelIndex];
452 |
453 | [self.ContentScrollView setContentOffset:CGPointMake(self.CurrentPanelIndex * 320, 0) animated:YES];
454 | //Call Back, if applicable
455 | if (LastPanelIndex != self.CurrentPanelIndex) { //Keeps from making the callback when just bouncing and not actually changing pages
456 | if ([(id)delegate respondsToSelector:@selector(introductionDidChangeToPanel:withIndex:)]) {
457 | [delegate introductionDidChangeToPanel:Panels[self.CurrentPanelIndex] withIndex:self.CurrentPanelIndex];
458 | }
459 | }
460 | }
461 |
462 | -(void)buildFooterView{
463 | //Build Page Control
464 | if (self.device == 1) {
465 | self.PageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, (self.ContentScrollView.frame.origin.y + self.ContentScrollView.frame.size.height + PAGE_CONTROL_PADDING), self.frame.size.width, 36)];
466 | } else {
467 | self.PageControl = [[UIPageControl alloc] initWithFrame:CGRectMake((self.frame.size.width - 185)/2, (self.ContentScrollView.frame.origin.y + self.ContentScrollView.frame.size.height + PAGE_CONTROL_PADDING), 185, 36)];
468 | }
469 | [self.PageControl setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
470 | [self.PageControl addTarget:self action:@selector(showPanelAtPageControl) forControlEvents:UIControlEventValueChanged];
471 |
472 | self.PageControl.numberOfPages = Panels.count;
473 | [self addSubview:self.PageControl];
474 |
475 |
476 | //Build Skip Button
477 | if (LanguageDirection == MYLanguageDirectionRightToLeft) {
478 | self.SkipButton = [[UIButton alloc] initWithFrame:CGRectMake(0, self.PageControl.frame.origin.y, 80, self.PageControl.frame.size.height)];
479 | self.PageControl.currentPage = panelViews.count - 1;
480 | }
481 | else {
482 | // self.SkipButton = [[UIButton alloc] initWithFrame:CGRectMake(self.ContentScrollView.frame.size.width - 80, self.PageControl.frame.origin.y, 80, self.PageControl.frame.size.height)];
483 | self.SkipButton = [[UIButton alloc] initWithFrame:CGRectMake(self.ContentScrollView.frame.size.width - 80, self.PageControl.frame.origin.y, 80, self.PageControl.frame.size.height)];
484 | }
485 |
486 | [self.SkipButton setAutoresizingMask: UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin];
487 | [self.SkipButton setTitle:NSLocalizedString(@"Skip", nil) forState:UIControlStateNormal];
488 | [self.SkipButton addTarget:self action:@selector(skipIntroduction) forControlEvents:UIControlEventTouchUpInside];
489 | [self addSubview:self.SkipButton];
490 | }
491 |
492 | -(void)setContentScrollViewHeightForPanelIndex:(NSInteger)panelIndex animated:(BOOL)animated{
493 | CGFloat newPanelHeight = [panelViews[panelIndex] frame].size.height;
494 |
495 | if (animated){
496 | [UIView animateWithDuration:0.3 animations:^{
497 | self.ContentScrollView.frame = CGRectMake(self.ContentScrollView.frame.origin.x, self.ContentScrollView.frame.origin.y, self.ContentScrollView.frame.size.width, newPanelHeight);
498 | self.PageControl.frame = CGRectMake(self.PageControl.frame.origin.x, (self.ContentScrollView.frame.origin.y + self.ContentScrollView.frame.size.height + PAGE_CONTROL_PADDING), self.PageControl.frame.size.width, self.PageControl.frame.size.height);
499 |
500 | self.SkipButton.frame = CGRectMake(self.SkipButton.frame.origin.x, (self.ContentScrollView.frame.origin.y + self.ContentScrollView.frame.size.height + PAGE_CONTROL_PADDING), self.SkipButton.frame.size.width, self.SkipButton.frame.size.height);
501 | }];
502 | }
503 | else {
504 | self.ContentScrollView.frame = CGRectMake(self.ContentScrollView.frame.origin.x, self.ContentScrollView.frame.origin.y, self.ContentScrollView.frame.size.width, newPanelHeight);
505 |
506 | self.PageControl.frame = CGRectMake(self.PageControl.frame.origin.x, (self.ContentScrollView.frame.origin.y + self.ContentScrollView.frame.size.height + PAGE_CONTROL_PADDING), self.PageControl.frame.size.width, self.PageControl.frame.size.height);
507 | self.SkipButton.frame = CGRectMake(self.SkipButton.frame.origin.x, (self.ContentScrollView.frame.origin.y + self.ContentScrollView.frame.size.height + PAGE_CONTROL_PADDING), self.SkipButton.frame.size.width, self.SkipButton.frame.size.height);
508 |
509 | }
510 |
511 | self.ContentScrollView.contentSize = CGSizeMake(self.ContentScrollView.contentSize.width, newPanelHeight);
512 | }
513 |
514 | #pragma mark - Header Content
515 |
516 | -(void)setHeaderText:(NSString *)headerText{
517 | self.HeaderLabel.hidden = NO;
518 | self.HeaderImageView.hidden = YES;
519 | self.HeaderLabel.text = headerText;
520 | }
521 |
522 | -(void)setHeaderImage:(UIImage *)headerImage {
523 | self.HeaderLabel.hidden = YES;
524 | self.HeaderImageView.hidden = NO;
525 | self.HeaderImageView.image = headerImage;
526 | }
527 |
528 | #pragma mark - Introduction Content
529 |
530 | -(void)setBackgroundImage:(UIImage *)backgroundImage{
531 | self.BackgroundImageView.image = backgroundImage;
532 | [self.BackgroundImageView setAutoresizingMask: UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
533 | }
534 |
535 | -(void)setBackgroundColor:(UIColor *)backgroundColor {
536 | self.BackgroundImageView.backgroundColor = backgroundColor;
537 | [self.BackgroundImageView setAutoresizingMask: UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
538 | }
539 |
540 | #pragma mark - Show/Hide
541 |
542 | -(void)showInView:(UIView *)view animateDuration:(CGFloat)duration{
543 | //Add introduction view
544 | self.alpha = 0;
545 | [view addSubview:self];
546 |
547 | //Fade in
548 | [UIView animateWithDuration:duration animations:^{
549 | self.alpha = 1;
550 | }];
551 | }
552 |
553 | -(void)hideWithFadeOutDuration:(CGFloat)duration{
554 | //Fade out
555 | [UIView animateWithDuration:duration animations:^{
556 | self.alpha = 0;
557 | } completion:nil];
558 | }
559 |
560 | -(void)makePanelVisibleAtIndex:(NSInteger)panelIndex{
561 | if (LanguageDirection == MYLanguageDirectionLeftToRight) {
562 | [UIView animateWithDuration:0.3 animations:^{
563 | for (int ii = 0; ii < panelViews.count; ii++) {
564 | if (ii == panelIndex) {
565 | [panelViews[ii] setAlpha:1];
566 | }
567 | else {
568 | [panelViews[ii] setAlpha:0];
569 | }
570 | }
571 | }];
572 | }
573 | else {
574 | [UIView animateWithDuration:0.3 animations:^{
575 | for (int ii = panelViews.count-1; ii > 0; ii--) {
576 | if (ii == panelIndex) {
577 | [panelViews[ii] setAlpha:1];
578 | }
579 | else {
580 | [panelViews[ii] setAlpha:0];
581 | }
582 | }
583 | }];
584 | }
585 | }
586 |
587 | -(void)skipIntroduction{
588 | if ([(id)delegate respondsToSelector:@selector(introductionDidFinishWithType:)]) {
589 | [delegate introductionDidFinishWithType:MYFinishTypeSkipButton];
590 | }
591 |
592 | [self hideWithFadeOutDuration:0.3];
593 | }
594 |
595 | #pragma mark - UIScrollView Delegate
596 |
597 | -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
598 | if (LanguageDirection == MYLanguageDirectionLeftToRight) {
599 | self.CurrentPanelIndex = scrollView.contentOffset.x/self.ContentScrollView.frame.size.width;
600 |
601 | //remove self if you are at the end of the introduction
602 | if (self.CurrentPanelIndex == (panelViews.count)) {
603 | if ([(id)delegate respondsToSelector:@selector(introductionDidFinishWithType:)]) {
604 | [delegate introductionDidFinishWithType:MYFinishTypeSwipeOut];
605 | }
606 | }
607 | else {
608 | //Update Page Control
609 | LastPanelIndex = self.PageControl.currentPage;
610 | self.PageControl.currentPage = self.CurrentPanelIndex;
611 |
612 | //Format and show new content
613 | [self setContentScrollViewHeightForPanelIndex:self.CurrentPanelIndex animated:YES];
614 | [self makePanelVisibleAtIndex:(NSInteger)self.CurrentPanelIndex];
615 |
616 | //Call Back, if applicable
617 | if (LastPanelIndex != self.CurrentPanelIndex) { //Keeps from making the callback when just bouncing and not actually changing pages
618 | if ([(id)delegate respondsToSelector:@selector(introductionDidChangeToPanel:withIndex:)]) {
619 | [delegate introductionDidChangeToPanel:Panels[self.CurrentPanelIndex] withIndex:self.CurrentPanelIndex];
620 | }
621 | }
622 | }
623 | }
624 | else if(LanguageDirection == MYLanguageDirectionRightToLeft){
625 | self.CurrentPanelIndex = (scrollView.contentOffset.x-320)/self.ContentScrollView.frame.size.width;
626 |
627 | //remove self if you are at the end of the introduction
628 | if (self.CurrentPanelIndex == -1) {
629 | if ([(id)delegate respondsToSelector:@selector(introductionDidFinishWithType:)]) {
630 | [delegate introductionDidFinishWithType:MYFinishTypeSwipeOut];
631 | }
632 | }
633 | else {
634 | //Update Page Control
635 | LastPanelIndex = self.PageControl.currentPage;
636 | self.PageControl.currentPage = self.CurrentPanelIndex;
637 |
638 | //Format and show new content
639 | [self setContentScrollViewHeightForPanelIndex:self.CurrentPanelIndex animated:YES];
640 | [self makePanelVisibleAtIndex:(NSInteger)self.CurrentPanelIndex];
641 |
642 | //Call Back, if applicable
643 | if (LastPanelIndex != self.CurrentPanelIndex) { //Keeps from making the callback when just bouncing and not actually changing pages
644 | if ([(id)delegate respondsToSelector:@selector(introductionDidChangeToPanel:withIndex:)]) {
645 | [delegate introductionDidChangeToPanel:Panels[self.CurrentPanelIndex] withIndex:self.CurrentPanelIndex];
646 | }
647 | }
648 | }
649 | }
650 | }
651 |
652 | -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
653 | if (LanguageDirection == MYLanguageDirectionLeftToRight) {
654 | if (self.CurrentPanelIndex == (panelViews.count - 1)) {
655 | self.alpha = ((self.ContentScrollView.frame.size.width*panelViews.count)-self.ContentScrollView.contentOffset.x)/self.ContentScrollView.frame.size.width;
656 | }
657 | }
658 | else if (LanguageDirection == MYLanguageDirectionRightToLeft){
659 | if (self.CurrentPanelIndex == 0) {
660 | self.alpha = self.ContentScrollView.contentOffset.x/self.ContentScrollView.frame.size.width;
661 | }
662 | }
663 | }
664 |
665 | #pragma mark - Support Methods
666 |
667 | +(BOOL)runningiOS7{
668 | NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
669 | if (currSysVer.floatValue >= 7.0) {
670 | return YES;
671 | }
672 |
673 | return NO;
674 | }
675 |
676 | @end
677 |
--------------------------------------------------------------------------------