├── .gitignore ├── Android ├── .DS_Store └── TutorialViewSample │ ├── .DS_Store │ ├── .gradle │ ├── 1.10 │ │ └── taskArtifacts │ │ │ ├── cache.properties │ │ │ ├── cache.properties.lock │ │ │ ├── fileHashes.bin │ │ │ ├── fileSnapshots.bin │ │ │ ├── outputFileStates.bin │ │ │ └── taskArtifacts.bin │ └── 1.6 │ │ └── taskArtifacts │ │ ├── cache.properties │ │ ├── cache.properties.lock │ │ ├── fileHashes.bin │ │ ├── fileSnapshots.bin │ │ ├── outputFileStates.bin │ │ └── taskArtifacts.bin │ ├── .idea │ ├── .name │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── dictionaries │ │ └── davidbenko.xml │ ├── encodings.xml │ ├── gradle.xml │ ├── libraries │ │ └── android_support_v4.xml │ ├── misc.xml │ ├── modules.xml │ ├── scopes │ │ └── scope_settings.xml │ ├── vcs.xml │ └── workspace.xml │ ├── TutorialViewSample-TutorialViewSample.iml │ ├── TutorialViewSample.iml │ ├── TutorialViewSample │ ├── .DS_Store │ ├── TutorialViewSample-TutorialViewSample.iml │ ├── build.gradle │ ├── build │ │ ├── apk │ │ │ └── TutorialViewSample-debug-unaligned.apk │ │ ├── classes │ │ │ └── debug │ │ │ │ ├── TutorialView │ │ │ │ ├── Arrow.class │ │ │ │ └── TutorialView.class │ │ │ │ └── com │ │ │ │ └── prndl │ │ │ │ └── tutorialviewsample │ │ │ │ ├── BuildConfig.class │ │ │ │ ├── ExampleActivity.class │ │ │ │ ├── R$attr.class │ │ │ │ ├── R$dimen.class │ │ │ │ ├── R$drawable.class │ │ │ │ ├── R$id.class │ │ │ │ ├── R$layout.class │ │ │ │ ├── R$menu.class │ │ │ │ ├── R$string.class │ │ │ │ ├── R$style.class │ │ │ │ └── R.class │ │ ├── dex │ │ │ └── debug │ │ │ │ └── classes.dex │ │ ├── incremental │ │ │ ├── aidl │ │ │ │ └── debug │ │ │ │ │ └── dependency.store │ │ │ ├── mergeAssets │ │ │ │ └── debug │ │ │ │ │ └── merger.xml │ │ │ └── mergeResources │ │ │ │ └── debug │ │ │ │ └── merger.xml │ │ ├── libs │ │ │ └── TutorialViewSample-debug.ap_ │ │ ├── manifests │ │ │ └── debug │ │ │ │ └── AndroidManifest.xml │ │ ├── pre-dexed │ │ │ └── debug │ │ │ │ └── android-support-v4-98fd70644da2c8bdd90029326df3569200bdbbda.jar │ │ ├── res │ │ │ └── all │ │ │ │ └── debug │ │ │ │ ├── drawable-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── drawable-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── layout │ │ │ │ └── activity_main.xml │ │ │ │ ├── menu │ │ │ │ └── main.xml │ │ │ │ ├── values-sw720dp-land │ │ │ │ └── values.xml │ │ │ │ ├── values-v11 │ │ │ │ └── values.xml │ │ │ │ ├── values-v14 │ │ │ │ └── values.xml │ │ │ │ └── values │ │ │ │ └── values.xml │ │ └── source │ │ │ ├── buildConfig │ │ │ └── debug │ │ │ │ └── com │ │ │ │ └── prndl │ │ │ │ └── tutorialviewsample │ │ │ │ └── BuildConfig.java │ │ │ └── r │ │ │ └── debug │ │ │ └── com │ │ │ └── prndl │ │ │ └── tutorialviewsample │ │ │ └── R.java │ ├── libs │ │ └── android-support-v4.jar │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── ic_launcher-web.png │ │ ├── java │ │ ├── TutorialView │ │ │ ├── Arrow.java │ │ │ └── TutorialView.java │ │ └── com │ │ │ └── prndl │ │ │ └── tutorialviewsample │ │ │ └── ExampleActivity.java │ │ └── res │ │ ├── drawable-hdpi │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ │ ├── drawable-xxhdpi │ │ └── ic_launcher.png │ │ ├── layout │ │ └── activity_main.xml │ │ ├── menu │ │ └── main.xml │ │ ├── values-sw600dp │ │ └── dimens.xml │ │ ├── values-sw720dp-land │ │ └── dimens.xml │ │ ├── values-v11 │ │ └── styles.xml │ │ ├── values-v14 │ │ └── styles.xml │ │ └── values │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── local.properties │ └── settings.gradle ├── README.md └── iOS ├── .DS_Store ├── Arrow.h ├── Arrow.m ├── TutorialView.h ├── TutorialView.m └── TutorialViewSample ├── .DS_Store ├── TutorialViewSample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── TutorialViewSample.xccheckout │ └── xcuserdata │ │ └── davidbenko.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── davidbenko.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ ├── TutorialViewSample.xcscheme │ └── xcschememanagement.plist └── TutorialViewSample ├── .DS_Store ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── PRNDLAppDelegate.h ├── PRNDLAppDelegate.m ├── PRNDLMainViewController.h ├── PRNDLMainViewController.m ├── TutorialViewSample-Info.plist ├── TutorialViewSample-Prefix.pch ├── en.lproj ├── InfoPlist.strings └── PRNDLMainViewController.xib └── main.m /.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 | profile 13 | *.moved-aside 14 | DerivedData 15 | .idea/ 16 | *.hmap 17 | *.xccheckout 18 | *.xcuserstate 19 | xcuserdata 20 | #CocoaPods 21 | Pods -------------------------------------------------------------------------------- /Android/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/.DS_Store -------------------------------------------------------------------------------- /Android/TutorialViewSample/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.DS_Store -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.10/taskArtifacts/cache.properties: -------------------------------------------------------------------------------- 1 | #Tue Apr 22 13:20:00 EDT 2014 2 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.10/taskArtifacts/cache.properties.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.10/taskArtifacts/cache.properties.lock -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.10/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.10/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.10/taskArtifacts/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.10/taskArtifacts/fileSnapshots.bin -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.10/taskArtifacts/outputFileStates.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.10/taskArtifacts/outputFileStates.bin -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.10/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.10/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.6/taskArtifacts/cache.properties: -------------------------------------------------------------------------------- 1 | #Mon May 20 15:22:39 EDT 2013 2 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.6/taskArtifacts/cache.properties.lock: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.6/taskArtifacts/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.6/taskArtifacts/fileHashes.bin -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.6/taskArtifacts/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.6/taskArtifacts/fileSnapshots.bin -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.6/taskArtifacts/outputFileStates.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.6/taskArtifacts/outputFileStates.bin -------------------------------------------------------------------------------- /Android/TutorialViewSample/.gradle/1.6/taskArtifacts/taskArtifacts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/.gradle/1.6/taskArtifacts/taskArtifacts.bin -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/.name: -------------------------------------------------------------------------------- 1 | TutorialViewSample -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/dictionaries/davidbenko.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/libraries/android_support_v4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Abstraction issues 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 47 | 48 | 49 | 67 | 74 | 75 | 76 | 87 | 88 | 101 | 102 | 103 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 125 | 126 | localhost 127 | 5050 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 140 | 141 | 142 | 143 | 144 | 145 | 1.6 146 | 147 | 152 | 153 | 154 | 155 | 156 | 157 | Android API 8 Platform 158 | 159 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample-TutorialViewSample.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 15 | 16 | 17 | 18 | 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 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/.DS_Store -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/TutorialViewSample-TutorialViewSample.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 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 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'android' 2 | 3 | android { 4 | compileSdkVersion 19 5 | buildToolsVersion "19.0.3" 6 | 7 | defaultConfig { 8 | minSdkVersion 8 9 | targetSdkVersion 19 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | runProguard false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(dir: 'libs', include: ['*.jar']) 23 | } -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/apk/TutorialViewSample-debug-unaligned.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/apk/TutorialViewSample-debug-unaligned.apk -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/TutorialView/Arrow.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/TutorialView/Arrow.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/TutorialView/TutorialView.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/TutorialView/TutorialView.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/BuildConfig.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/BuildConfig.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/ExampleActivity.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/ExampleActivity.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$attr.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$attr.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$dimen.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$dimen.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$drawable.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$drawable.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$id.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$id.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$layout.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$layout.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$menu.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$menu.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$string.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$string.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$style.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R$style.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/classes/debug/com/prndl/tutorialviewsample/R.class -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/dex/debug/classes.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/dex/debug/classes.dex -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/incremental/aidl/debug/dependency.store: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/incremental/mergeAssets/debug/merger.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/incremental/mergeResources/debug/merger.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 16 | 21 | 26 | 31 | 36 | 39 | 16dp 40 | 41 | 16dp 42 | 43 | 44 | 47 | Settings 48 | 49 | TutorialViewSample 50 | 51 | Hello world! 52 | 53 | 54 | 57 | 58 | 68 | 69 | 75 | 76 | 79 | 128dp 80 | 81 | 82 | 85 | 86 | 92 | 93 | 96 | 97 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/libs/TutorialViewSample-debug.ap_: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/libs/TutorialViewSample-debug.ap_ -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/manifests/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/pre-dexed/debug/android-support-v4-98fd70644da2c8bdd90029326df3569200bdbbda.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/pre-dexed/debug/android-support-v4-98fd70644da2c8bdd90029326df3569200bdbbda.jar -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/values-sw720dp-land/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 128dp 8 | 9 | 10 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/values-v11/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/values-v14/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/res/all/debug/values/values.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 16dp 8 | 16dp 9 | 10 | 11 | 12 | Settings 13 | TutorialViewSample 14 | Hello world! 15 | 16 | 17 | 18 | 25 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/source/buildConfig/debug/com/prndl/tutorialviewsample/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Automatically generated file. DO NOT MODIFY 3 | */ 4 | package com.prndl.tutorialviewsample; 5 | 6 | public final class BuildConfig { 7 | public static final boolean DEBUG = Boolean.parseBoolean("true"); 8 | public static final String PACKAGE_NAME = "com.prndl.tutorialviewsample"; 9 | public static final String BUILD_TYPE = "debug"; 10 | public static final String FLAVOR = ""; 11 | public static final int VERSION_CODE = 1; 12 | public static final String VERSION_NAME = "1.0"; 13 | } 14 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/build/source/r/debug/com/prndl/tutorialviewsample/R.java: -------------------------------------------------------------------------------- 1 | /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 | * 3 | * This class was automatically generated by the 4 | * aapt tool from the resource data it found. It 5 | * should not be modified by hand. 6 | */ 7 | 8 | package com.prndl.tutorialviewsample; 9 | 10 | public final class R { 11 | public static final class attr { 12 | } 13 | public static final class dimen { 14 | public static final int activity_horizontal_margin=0x7f040000; 15 | public static final int activity_vertical_margin=0x7f040001; 16 | } 17 | public static final class drawable { 18 | public static final int ic_launcher=0x7f020000; 19 | } 20 | public static final class id { 21 | public static final int action_settings=0x7f080001; 22 | public static final int layout=0x7f080000; 23 | } 24 | public static final class layout { 25 | public static final int activity_main=0x7f030000; 26 | } 27 | public static final class menu { 28 | public static final int main=0x7f070000; 29 | } 30 | public static final class string { 31 | public static final int action_settings=0x7f050000; 32 | public static final int app_name=0x7f050001; 33 | public static final int hello_world=0x7f050002; 34 | } 35 | public static final class style { 36 | /** 37 | Theme customizations available in newer API levels can go in 38 | res/values-vXX/styles.xml, while customizations related to 39 | backward-compatibility can go here. 40 | 41 | API 11 theme customizations can go here. 42 | API 14 theme customizations can go here. 43 | */ 44 | public static final int AppBaseTheme=0x7f060000; 45 | /** All customizations that are NOT specific to a particular API-level can go here. 46 | */ 47 | public static final int AppTheme=0x7f060001; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/libs/android-support-v4.jar -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/java/TutorialView/Arrow.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package TutorialView; 4 | 5 | import android.graphics.Path; 6 | import android.graphics.Point; 7 | 8 | public class Arrow { 9 | 10 | public static final float ARROW_HEAD_LENGTH_RATIO = 8.5f; 11 | 12 | private Point head; 13 | private Point tail; 14 | private Boolean curved; 15 | private Boolean animated; 16 | private String description; 17 | private Path path; 18 | 19 | public Arrow() { 20 | this.head = new Point(0,0); 21 | this.tail = new Point(0,0); 22 | this.curved = true; 23 | this.animated = true; 24 | this.description = ""; 25 | this.path = new Path(); 26 | } 27 | public void setHead(int x, int y){ 28 | this.setHead(new Point(x,y)); 29 | } 30 | public void setHead(Point point){ 31 | this.head = point; 32 | this.generatePath(); 33 | } 34 | public void setTail(Point point){ 35 | this.tail = point; 36 | this.generatePath(); 37 | } 38 | public void setTail(int x, int y){ 39 | this.setTail(new Point(x,y)); 40 | } 41 | public void setCurved(Boolean curved){ 42 | this.curved = curved; 43 | this.generatePath(); 44 | } 45 | public boolean getAnimated(){ 46 | return this.animated; 47 | } 48 | public void setAnimated(boolean animated){ 49 | this.animated = animated; 50 | } 51 | public void setAnimated(Boolean animated){ 52 | this.animated = animated; 53 | } 54 | public void setDescription(String description){ 55 | this.description = description; 56 | } 57 | private void generatePath(){ 58 | Boolean shouldCurve = (head.x == tail.x || head.y == tail.y) ? false : this.curved; 59 | 60 | Path path = new Path(); 61 | path.moveTo(this.head.x,this.head.y); 62 | if(shouldCurve) path.quadTo(this.head.x,this.tail.y,this.tail.x,this.tail.y); 63 | else path.lineTo(this.tail.x,this.tail.y); 64 | 65 | //Calculate Arrow Head 66 | Point A = shouldCurve ? new Point(this.head.x,this.tail.y) : this.tail; 67 | Point B = this.head; 68 | 69 | // Vector from A to B: 70 | Point AB = new Point(B.x - A.x, B.y - A.y); 71 | 72 | // Length of AB == distance from A to B: 73 | double d = Math.hypot(AB.x, AB.y); 74 | 75 | // Arrow size == distance from C to B. 76 | float arrowSize = getArrowHeadLength(d); 77 | 78 | // Vector from C to B: 79 | Point CB = new Point((int)(AB.x * arrowSize/d), (int)(AB.y * arrowSize/d)); 80 | 81 | // Compute P and Q: 82 | Point P = new Point(B.x - CB.x - CB.y, B.y - CB.y + CB.x); 83 | Point Q = new Point(B.x - CB.x + CB.y, B.y - CB.y - CB.x); 84 | 85 | path.moveTo(this.head.x,this.head.y); 86 | path.lineTo(P.x,P.y); 87 | 88 | path.moveTo(this.head.x,this.head.y); 89 | path.lineTo(Q.x,Q.y); 90 | 91 | this.path = path; 92 | } 93 | private float getArrowHeadLength(double hypotenuse){ 94 | return (float)(hypotenuse / ARROW_HEAD_LENGTH_RATIO); 95 | } 96 | public Path getPath(){ 97 | return this.path; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/java/TutorialView/TutorialView.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package TutorialView; 4 | 5 | import android.content.Context; 6 | import android.graphics.*; 7 | import android.os.Build; 8 | import android.os.Bundle; 9 | import android.util.Log; 10 | import android.view.MotionEvent; 11 | import android.view.View; 12 | 13 | import java.util.ArrayList; 14 | 15 | public class TutorialView extends View { 16 | 17 | 18 | public static final float VIEW_ALPHA = 0.8f; 19 | public static final String VIEW_COLOR = "#000000"; 20 | public static final float LINE_WIDTH = 5.0f; 21 | public static final String ARROW_COLOR = "#FFFFFF"; 22 | public static final float DRAW_ANIMATION_SPEED = 30.0f; 23 | public static final float TIP_FRAME_PADDING = 15.0f; 24 | 25 | private static Paint paint; 26 | private Path pathAnimated; 27 | private Path pathNoAnimation; 28 | private Context context; 29 | float[] dashes = { 0.0f, Float.MAX_VALUE }; 30 | private ArrayList arrows; 31 | 32 | public TutorialView(Context context) { 33 | super(context); 34 | 35 | this.context=context; 36 | this.setBackgroundColor(Color.parseColor(VIEW_COLOR)); 37 | if(Build.VERSION.SDK_INT >= 11) this.setAlpha(VIEW_ALPHA); 38 | this.arrows = new ArrayList(); 39 | paint = new Paint(); 40 | paint.setColor(Color.parseColor(ARROW_COLOR)); 41 | paint.setStrokeWidth(LINE_WIDTH); 42 | paint.setAntiAlias(true); 43 | paint.setStrokeCap(Paint.Cap.ROUND); 44 | paint.setStrokeJoin(Paint.Join.ROUND); 45 | paint.setStyle(Paint.Style.STROKE); 46 | } 47 | 48 | private Point getClosestPointInRectToPoint(Rect rect, Point point){ 49 | float xMin = rect.left; 50 | float yMin = rect.top; 51 | float xMax = rect.right; 52 | float yMax = rect.bottom; 53 | 54 | float closeX; 55 | float closeY; 56 | 57 | if(point.x < xMin) closeX = xMin; 58 | else if (point.x > xMax) closeX = xMax; 59 | else closeX = point.x; 60 | 61 | if(point.y < yMin) closeY = yMin; 62 | else if (point.y > yMax) closeY = yMax; 63 | else closeY = point.y; 64 | 65 | return new Point((int)closeX,(int)closeY); 66 | } 67 | 68 | public void addArrow(Arrow arrow){ 69 | this.arrows.add(arrow); 70 | generatePath(); 71 | } 72 | private void generatePath(){ 73 | Path pAnimated = new Path(); 74 | Path pNoAnimated = new Path(); 75 | for (Arrow a : this.arrows) 76 | if(a.getAnimated()) pAnimated.addPath(a.getPath()); 77 | else pNoAnimated.addPath(a.getPath()); 78 | 79 | this.pathAnimated = pAnimated; 80 | this.pathNoAnimation = pNoAnimated; 81 | } 82 | 83 | @Override 84 | public void onDraw(Canvas canvas) { 85 | super.onDraw(canvas); 86 | 87 | if(this.arrows.isEmpty()){ 88 | Log.i("TutorialView","No Arrows to Draw!"); 89 | return; 90 | } 91 | 92 | /* 93 | * Animated Arrows 94 | */ 95 | 96 | if(!pathAnimated.isEmpty()){ 97 | dashes[0]+= DRAW_ANIMATION_SPEED; 98 | paint.setPathEffect(new DashPathEffect(dashes, 0)); 99 | canvas.drawPath(pathAnimated, paint); 100 | invalidate(); 101 | } 102 | 103 | /* 104 | * Non-Animated Arrows 105 | */ 106 | 107 | if(!pathNoAnimation.isEmpty()){ 108 | paint.setPathEffect(null); 109 | canvas.drawPath(pathNoAnimation,paint); 110 | } 111 | } 112 | 113 | public void dismissView(Boolean animated){ 114 | this.setVisibility(View.GONE); 115 | } 116 | 117 | @Override 118 | public boolean onTouchEvent(MotionEvent event) { 119 | this.dismissView(true); 120 | return true; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/java/com/prndl/tutorialviewsample/ExampleActivity.java: -------------------------------------------------------------------------------- 1 | package com.prndl.tutorialviewsample; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Point; 5 | import android.os.Bundle; 6 | 7 | import TutorialView.Arrow; 8 | import TutorialView.TutorialView; 9 | 10 | /** 11 | * Created by davidbenko on 4/22/14. 12 | */ 13 | public class ExampleActivity extends Activity { 14 | 15 | @Override 16 | public void onCreate(Bundle data){ 17 | super.onCreate( data ); 18 | 19 | TutorialView t = new TutorialView(this); 20 | Arrow a = new Arrow(); 21 | a.setHead(new Point(100,100)); 22 | a.setTail(new Point(300, 300)); 23 | t.addArrow(a); 24 | 25 | 26 | a = new Arrow(); 27 | a.setHead(new Point(500, 700)); 28 | a.setTail(new Point(200, 400)); 29 | a.setCurved(false); 30 | t.addArrow(a); 31 | 32 | setContentView(t); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/TutorialViewSample/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 128dp 5 | 6 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TutorialViewSample 5 | 6 | Settings 7 | 8 | Hello world! 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/TutorialViewSample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | mavenCentral() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:0.9.+' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | mavenCentral() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/Android/TutorialViewSample/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Android/TutorialViewSample/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 10 15:27:10 PDT 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip 7 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/local.properties: -------------------------------------------------------------------------------- 1 | ## This file is automatically generated by Android Studio. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must *NOT* be checked into Version Control Systems, 5 | # as it contains information specific to your local configuration. 6 | # 7 | # Location of the SDK. This is only used by Gradle. 8 | # For customization when using a Version Control System, please read the 9 | # header note. 10 | #Tue Apr 22 13:02:03 EDT 2014 11 | sdk.dir=/Users/davidbenko/android-sdks 12 | -------------------------------------------------------------------------------- /Android/TutorialViewSample/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':TutorialViewSample' 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TutorialView 2 | ============ 3 | 4 | TutorialView is a project which will draw animated arrows over your app to instruct the user on the functions of the application. It dynamically draws arrows to the screen based on a head and tail point for the arrow. It will automatically determine the direction and curve of the arrow and draw it to screen with animation. The view will disappear after it has been tapped by the user. 5 | 6 | The project consists of two classes: the TutorialView and the Arrow. 7 | 8 | The Arrow class is responsible for determining the size and shape of the arrow, its location on the screen, and whether it should be curved and/or animated. 9 | 10 | The TutorialView class is the actual overlay responsible for drawing to the screen. On iOS, it uses Core Graphics and Core Animation to render the arrows and the ‘drawing’ animation. On Android, it uses the Path class and other android.graphics.* classes. 11 | 12 | This project has been tested on iOS6.X and iOS7 as well as Android 4.X.X. 13 | Feel free to fork me to add updates and bug fixes! 14 | 15 | 16 | 17 | 18 | License 19 | ============ 20 | 21 | The MIT License (MIT) 22 | 23 | Copyright (c) 2013 PRNDL Development Studios, LLC 24 | 25 | Permission is hereby granted, free of charge, to any person obtaining a copy 26 | of this software and associated documentation files (the "Software"), to deal 27 | in the Software without restriction, including without limitation the rights 28 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 29 | copies of the Software, and to permit persons to whom the Software is 30 | furnished to do so, subject to the following conditions: 31 | 32 | The above copyright notice and this permission notice shall be included in 33 | all copies or substantial portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 40 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 41 | THE SOFTWARE. -------------------------------------------------------------------------------- /iOS/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/iOS/.DS_Store -------------------------------------------------------------------------------- /iOS/Arrow.h: -------------------------------------------------------------------------------- 1 | //The MIT License (MIT) 2 | // 3 | // 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy 5 | //of this software and associated documentation files (the "Software"), to deal 6 | //in the Software without restriction, including without limitation the rights 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | //copies of the Software, and to permit persons to whom the Software is 9 | //furnished to do so, subject to the following conditions: 10 | // 11 | //The above copyright notice and this permission notice shall be included in 12 | //all copies or substantial portions of the Software. 13 | // 14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | //THE SOFTWARE. 21 | // 22 | //Created By David Benko on 5/15/2013 23 | 24 | #import 25 | #import 26 | #import 27 | 28 | #define ARROW_HEAD_LENGTH(arrowLen) arrowLen / 8.5f 29 | 30 | enum ArrowDirection { 31 | ArrowDirectionHT, // Draw arrow head to tail (default) 32 | ArrowDirectionTH // Draw arrow tail to head 33 | }; 34 | typedef enum ArrowDirection ArrowDirection; 35 | 36 | @interface Arrow : NSObject 37 | 38 | @property (nonatomic, assign) CGPoint head; 39 | @property (nonatomic, assign) CGPoint tail; 40 | @property (nonatomic, assign) BOOL curved; 41 | @property (nonatomic, assign) BOOL animated; 42 | @property (nonatomic, strong) NSString *description; 43 | @property (nonatomic, assign) CGMutablePathRef path; 44 | @property (nonatomic, assign) ArrowDirection direction; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /iOS/Arrow.m: -------------------------------------------------------------------------------- 1 | //The MIT License (MIT) 2 | // 3 | // 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy 5 | //of this software and associated documentation files (the "Software"), to deal 6 | //in the Software without restriction, including without limitation the rights 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | //copies of the Software, and to permit persons to whom the Software is 9 | //furnished to do so, subject to the following conditions: 10 | // 11 | //The above copyright notice and this permission notice shall be included in 12 | //all copies or substantial portions of the Software. 13 | // 14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | //THE SOFTWARE. 21 | // 22 | //Created By David Benko on 5/15/2013 23 | 24 | #import "Arrow.h" 25 | 26 | @implementation Arrow 27 | 28 | @synthesize head,tail; 29 | @synthesize curved,animated; 30 | @synthesize description; 31 | @synthesize path; 32 | 33 | #pragma mark - Lifecycle 34 | 35 | - (id) init 36 | { 37 | self = [super init]; 38 | if (self) 39 | { 40 | self.head = CGPointZero; 41 | self.tail = CGPointZero; 42 | self.curved = true; 43 | self.animated = true; 44 | self.description = @""; 45 | self.direction=ArrowDirectionHT; 46 | self.path = CGPathCreateMutable(); 47 | } 48 | return self; 49 | } 50 | 51 | -(void)dealloc { 52 | CGPathRelease(self.path); 53 | } 54 | 55 | #pragma mark - Setter methods 56 | 57 | - (void)setHead:(CGPoint)point{ 58 | head = point; 59 | [self generatePath]; 60 | } 61 | 62 | - (void)setHeadWithX:(CGFloat)x andY:(CGFloat)y { 63 | self.head = CGPointMake(x, y); 64 | } 65 | 66 | - (void)setTail:(CGPoint)point{ 67 | tail = point; 68 | [self generatePath]; 69 | } 70 | 71 | - (void)setTailWithX:(CGFloat)x andY:(CGFloat)y { 72 | self.tail = CGPointMake(x, y); 73 | } 74 | 75 | - (void)setCurved:(BOOL)shouldCurve { 76 | curved = shouldCurve; 77 | [self generatePath]; 78 | } 79 | 80 | -(void)setDirection:(ArrowDirection)drawDirection 81 | { 82 | _direction=drawDirection; 83 | [self generatePath]; 84 | } 85 | 86 | #pragma mark - Draw methods 87 | 88 | - (void)generatePath { 89 | 90 | //Early out if invalid path 91 | if(CGPointEqualToPoint(head,tail))return; 92 | 93 | CGMutablePathRef arrowPath = CGPathCreateMutable(); 94 | 95 | BOOL shouldCurve = (self.head.x == self.tail.x || self.head.y == self.tail.y) ? NO : self.curved; 96 | if (self.direction==ArrowDirectionHT) { 97 | CGPathMoveToPoint(arrowPath, nil, self.head.x, self.head.y); 98 | if(shouldCurve) 99 | CGPathAddQuadCurveToPoint(arrowPath, nil, self.head.x, self.tail.y, self.tail.x, self.tail.y); 100 | else CGPathAddLineToPoint(arrowPath, nil, self.tail.x, self.tail.y); 101 | }else 102 | { 103 | CGPathMoveToPoint(arrowPath, nil, self.tail.x, self.tail.y); 104 | if(shouldCurve) 105 | CGPathAddQuadCurveToPoint(arrowPath, nil, self.head.x, self.tail.y, self.head.x, self.head.y); 106 | else CGPathAddLineToPoint(arrowPath, nil, self.head.x, self.head.y); 107 | } 108 | 109 | //Calculate Arrow Head 110 | CGPoint A = shouldCurve ? CGPointMake(self.head.x, self.tail.y) : self.tail; 111 | CGPoint B = self.head; 112 | 113 | // Vector from A to B: 114 | CGPoint AB = CGPointMake(B.x - A.x, B.y - A.y); 115 | 116 | // Length of AB == distance from A to B: 117 | CGFloat d = hypotf(AB.x, AB.y); 118 | 119 | // Arrow size == distance from C to B. 120 | CGFloat arrowSize = ARROW_HEAD_LENGTH(d); 121 | 122 | // Vector from C to B: 123 | CGPoint CB = CGPointMake(AB.x * arrowSize/d, AB.y * arrowSize/d); 124 | 125 | // Compute P and Q: 126 | CGPoint P = CGPointMake(B.x - CB.x - CB.y, B.y - CB.y + CB.x); 127 | CGPoint Q = CGPointMake(B.x - CB.x + CB.y, B.y - CB.y - CB.x); 128 | 129 | CGPathMoveToPoint(arrowPath, nil, self.head.x, self.head.y); 130 | CGPathAddLineToPoint(arrowPath, nil, P.x, P.y); 131 | 132 | CGPathMoveToPoint(arrowPath, nil, self.head.x, self.head.y); 133 | CGPathAddLineToPoint(arrowPath, nil, Q.x, Q.y); 134 | 135 | CGPathRelease(self.path); 136 | self.path = arrowPath; 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /iOS/TutorialView.h: -------------------------------------------------------------------------------- 1 | //The MIT License (MIT) 2 | // 3 | // 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy 5 | //of this software and associated documentation files (the "Software"), to deal 6 | //in the Software without restriction, including without limitation the rights 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | //copies of the Software, and to permit persons to whom the Software is 9 | //furnished to do so, subject to the following conditions: 10 | // 11 | //The above copyright notice and this permission notice shall be included in 12 | //all copies or substantial portions of the Software. 13 | // 14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | //THE SOFTWARE. 21 | // 22 | //Created By David Benko on 5/15/2013 23 | 24 | #import 25 | #import 26 | #import 27 | #import "Arrow.h" 28 | 29 | #define VIEW_ALPHA 0.7f 30 | #define VIEW_COLOR [UIColor blackColor] 31 | #define LINE_WIDTH 1. 32 | #define ARROW_COLOR [[UIColor whiteColor] CGColor] 33 | #define DRAW_ANIMATION_SPEED 0.3f 34 | #define DISMISS_ANIMATION_SPEED 0.5f 35 | #define TIP_FRAME_PADDING 15. 36 | #define IOS_VERSION [[[UIDevice currentDevice] systemVersion] floatValue] 37 | #define DRAWS_ASYNC true 38 | 39 | @class TutorialView; 40 | 41 | @protocol TutorialViewDelegate 42 | @optional 43 | - (BOOL)tutorialView:(TutorialView *)tutorialView shouldDismissAnimated:(bool *)animated; 44 | - (void)tutorialView:(TutorialView *)tutorialView didDismissAnimated:(BOOL)animated; 45 | - (BOOL)tutorialView:(TutorialView *)tutorialView shouldDrawPath:(CGPathRef)path animated:(BOOL)animated; 46 | - (void)tutorialView:(TutorialView *)tutorialView didDrawPath:(CGPathRef)path; 47 | @end 48 | 49 | @interface TutorialView : UIView 50 | @property (nonatomic, assign) id delegate; 51 | - (void)addArrow:(Arrow *)arrow; 52 | - (void)dismissViewAnimated:(BOOL)animated completion:(void(^)(void))callback; 53 | @end 54 | 55 | -------------------------------------------------------------------------------- /iOS/TutorialView.m: -------------------------------------------------------------------------------- 1 | //The MIT License (MIT) 2 | // 3 | // 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy 5 | //of this software and associated documentation files (the "Software"), to deal 6 | //in the Software without restriction, including without limitation the rights 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | //copies of the Software, and to permit persons to whom the Software is 9 | //furnished to do so, subject to the following conditions: 10 | // 11 | //The above copyright notice and this permission notice shall be included in 12 | //all copies or substantial portions of the Software. 13 | // 14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | //THE SOFTWARE. 21 | // 22 | //Created By David Benko on 5/15/2013 23 | 24 | #import "TutorialView.h" 25 | 26 | @interface TutorialView () 27 | @property (nonatomic,strong) NSMutableArray *arrows; 28 | @property (nonatomic, assign) CGMutablePathRef pathNoAnimation; 29 | @property (nonatomic, assign) CGMutablePathRef pathAnimated; 30 | @end 31 | 32 | @implementation TutorialView 33 | 34 | @synthesize arrows; 35 | @synthesize delegate; 36 | 37 | - (id)initWithFrame:(CGRect)frame 38 | { 39 | self = [super initWithFrame:frame]; 40 | if (self) { 41 | // Initialization code 42 | [self setBackgroundColor:VIEW_COLOR]; 43 | [self setAlpha:VIEW_ALPHA]; 44 | [self setDelegate:nil]; 45 | arrows = [[NSMutableArray alloc]init]; 46 | UITapGestureRecognizer *singleFingerTap = 47 | [[UITapGestureRecognizer alloc] initWithTarget:self 48 | action:@selector(dismissView)]; 49 | [self addGestureRecognizer:singleFingerTap]; 50 | } 51 | 52 | return self; 53 | } 54 | 55 | // Only override drawRect: if you perform custom drawing. 56 | // An empty implementation adversely affects performance during animation. 57 | - (void)drawRect:(CGRect)rect 58 | { 59 | [self drawPath]; 60 | } 61 | 62 | - (void)layoutSubviews{ 63 | [super layoutSubviews]; 64 | } 65 | 66 | - (CGPoint)getClosestPointInRect:(CGRect)rect toPoint:(CGPoint)point { 67 | CGFloat x_min = rect.origin.x; 68 | CGFloat y_min = rect.origin.y; 69 | CGFloat x_max = rect.origin.x + rect.size.width; 70 | CGFloat y_max = rect.origin.y + rect.size.height; 71 | 72 | CGFloat close_x; 73 | CGFloat close_y; 74 | 75 | if (point.x < x_min) close_x = x_min; 76 | else if (point.x > x_max) close_x = x_max; 77 | else close_x = point.x; 78 | 79 | if (point.y < y_min) close_y = y_min; 80 | else if (point.y > y_max) close_y = y_max; 81 | else close_y = point.y; 82 | 83 | return CGPointMake(close_x,close_y); 84 | } 85 | 86 | - (void)addArrow:(Arrow *)arrow{ 87 | //NSLog(@"Arrow Head: %@",NSStringFromCGPoint(arrow.head)); 88 | //NSLog(@"Arrow Tail: %@",NSStringFromCGPoint(arrow.tail)); 89 | [self.arrows addObject:arrow]; 90 | [self generatePath]; 91 | [self setNeedsDisplay]; 92 | } 93 | 94 | - (void)drawPath{ 95 | if (self.arrows.count < 1){ 96 | NSLog(@"TutorialView No Arrows to Draw!"); 97 | return; 98 | }; 99 | 100 | //Remove old layers 101 | for(CALayer *layer in self.layer.sublayers) 102 | if([layer isMemberOfClass:[CAShapeLayer class]]) 103 | [layer removeFromSuperlayer]; 104 | 105 | bool drawAnimatedPath = true; 106 | bool drawNonAnimatedPath = true; 107 | 108 | if(!CGPathIsEmpty(self.pathAnimated)){ 109 | if([self.delegate respondsToSelector:@selector(tutorialView:shouldDrawPath:animated:)]) 110 | drawAnimatedPath = [self.delegate tutorialView:self shouldDrawPath:(CGPathRef)self.pathAnimated animated:true]; 111 | } 112 | else drawAnimatedPath = false; 113 | 114 | if(!CGPathIsEmpty(self.pathNoAnimation)){ 115 | if([self.delegate respondsToSelector:@selector(tutorialView:shouldDrawPath:animated:)]) 116 | drawNonAnimatedPath = [self.delegate tutorialView:self shouldDrawPath:(CGPathRef)self.pathNoAnimation animated:false]; 117 | } 118 | else drawNonAnimatedPath = false; 119 | 120 | if (drawAnimatedPath) { 121 | 122 | /* 123 | * Animated Arrows 124 | */ 125 | 126 | CAShapeLayer *pathLayer = [CAShapeLayer layer]; 127 | pathLayer.frame = self.bounds; 128 | pathLayer.path = self.pathAnimated; 129 | pathLayer.strokeColor = ARROW_COLOR; 130 | pathLayer.fillColor = nil; 131 | if (IOS_VERSION >= 6.0f) pathLayer.drawsAsynchronously = DRAWS_ASYNC; 132 | pathLayer.lineWidth = LINE_WIDTH; 133 | pathLayer.lineJoin = kCALineJoinBevel; 134 | [self.layer addSublayer:pathLayer]; 135 | CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 136 | pathAnimation.duration = DRAW_ANIMATION_SPEED; 137 | pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; 138 | pathAnimation.toValue = [NSNumber numberWithFloat:1.0f]; 139 | [pathLayer addAnimation:pathAnimation forKey:@"strokeEnd"]; 140 | 141 | if([self.delegate respondsToSelector:@selector(tutorialView:didDrawPath:)]) 142 | [self.delegate tutorialView:self didDrawPath:(CGPathRef)self.pathAnimated]; 143 | } 144 | 145 | if(drawNonAnimatedPath){ 146 | /* 147 | * Non-Animated Arrows 148 | */ 149 | 150 | CAShapeLayer *pathLayer = [CAShapeLayer layer]; 151 | pathLayer.frame = self.bounds; 152 | pathLayer.path = self.pathNoAnimation; 153 | pathLayer.strokeColor = ARROW_COLOR; 154 | if (IOS_VERSION >= 6.0f) pathLayer.drawsAsynchronously = DRAWS_ASYNC; 155 | pathLayer.fillColor = nil; 156 | pathLayer.lineWidth = LINE_WIDTH; 157 | pathLayer.lineJoin = kCALineJoinBevel; 158 | [self.layer addSublayer:pathLayer]; 159 | 160 | if([self.delegate respondsToSelector:@selector(tutorialView:didDrawPath:)]) 161 | [self.delegate tutorialView:self didDrawPath:(CGPathRef)self.pathNoAnimation]; 162 | } 163 | 164 | } 165 | 166 | - (void)generatePath{ 167 | CGMutablePathRef pAnimated = CGPathCreateMutable(); 168 | CGMutablePathRef pNoAnimated = CGPathCreateMutable(); 169 | for(Arrow *a in self.arrows) 170 | CGPathAddPath(a.animated ? pAnimated : pNoAnimated, nil, a.path); 171 | CGPathRelease(self.pathAnimated); 172 | CGPathRelease(self.pathNoAnimation); 173 | self.pathAnimated = pAnimated; 174 | self.pathNoAnimation = pNoAnimated; 175 | } 176 | 177 | - (void)dismissView{ 178 | [self dismissViewAnimated:YES completion:nil]; 179 | } 180 | 181 | - (void)dismissViewAnimated:(BOOL)animated completion:(void(^)(void))callback{ 182 | bool shouldAnimate = animated; 183 | bool shouldDismiss = true; 184 | if ([self.delegate respondsToSelector:@selector(tutorialView:shouldDismissAnimated:)]) 185 | shouldDismiss = [self.delegate tutorialView:self shouldDismissAnimated:&shouldAnimate]; 186 | if (!shouldDismiss) return; 187 | 188 | if(shouldAnimate){ 189 | [UIView animateWithDuration:DISMISS_ANIMATION_SPEED 190 | delay:0 191 | options:UIViewAnimationOptionLayoutSubviews 192 | animations:^{ 193 | self.alpha = 0.0f; 194 | } 195 | completion:^(BOOL success){ 196 | [self removeFromSuperview]; 197 | if(callback) callback(); 198 | if([self.delegate respondsToSelector:@selector(tutorialView:didDismissAnimated:)]) 199 | [self.delegate tutorialView:self didDismissAnimated:animated]; 200 | } 201 | ]; 202 | } 203 | else{ 204 | [self removeFromSuperview]; 205 | if(callback) callback(); 206 | if([self.delegate respondsToSelector:@selector(tutorialView:didDismissAnimated:)]) 207 | [self.delegate tutorialView:self didDismissAnimated:animated]; 208 | } 209 | } 210 | 211 | #pragma mark - Dealloc 212 | 213 | -(void)dealloc { 214 | CGPathRelease(self.pathAnimated); 215 | CGPathRelease(self.pathNoAnimation); 216 | } 217 | 218 | @end 219 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/iOS/TutorialViewSample/.DS_Store -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C390E63717474B2400CF3C8F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C390E63617474B2400CF3C8F /* UIKit.framework */; }; 11 | C390E63917474B2400CF3C8F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C390E63817474B2400CF3C8F /* Foundation.framework */; }; 12 | C390E63B17474B2400CF3C8F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C390E63A17474B2400CF3C8F /* CoreGraphics.framework */; }; 13 | C390E64117474B2400CF3C8F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C390E63F17474B2400CF3C8F /* InfoPlist.strings */; }; 14 | C390E64317474B2400CF3C8F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C390E64217474B2400CF3C8F /* main.m */; }; 15 | C390E64717474B2400CF3C8F /* PRNDLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C390E64617474B2400CF3C8F /* PRNDLAppDelegate.m */; }; 16 | C390E64917474B2400CF3C8F /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = C390E64817474B2400CF3C8F /* Default.png */; }; 17 | C390E64B17474B2400CF3C8F /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C390E64A17474B2400CF3C8F /* Default@2x.png */; }; 18 | C390E64D17474B2400CF3C8F /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C390E64C17474B2400CF3C8F /* Default-568h@2x.png */; }; 19 | C390E65017474B2400CF3C8F /* PRNDLMainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C390E64F17474B2400CF3C8F /* PRNDLMainViewController.m */; }; 20 | C390E65617474B2400CF3C8F /* PRNDLMainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = C390E65417474B2400CF3C8F /* PRNDLMainViewController.xib */; }; 21 | C3E6D2841753BCD400B837F9 /* TutorialView.m in Sources */ = {isa = PBXBuildFile; fileRef = C3E6D2831753BCD400B837F9 /* TutorialView.m */; }; 22 | C3E6D2871753BCF700B837F9 /* Arrow.m in Sources */ = {isa = PBXBuildFile; fileRef = C3E6D2861753BCF700B837F9 /* Arrow.m */; }; 23 | C3F307C21757DB5400F73CEB /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3F307C11757DB5400F73CEB /* QuartzCore.framework */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | C390E63317474B2400CF3C8F /* TutorialViewSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TutorialViewSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | C390E63617474B2400CF3C8F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 29 | C390E63817474B2400CF3C8F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 30 | C390E63A17474B2400CF3C8F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 31 | C390E63E17474B2400CF3C8F /* TutorialViewSample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TutorialViewSample-Info.plist"; sourceTree = ""; }; 32 | C390E64017474B2400CF3C8F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 33 | C390E64217474B2400CF3C8F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 34 | C390E64417474B2400CF3C8F /* TutorialViewSample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TutorialViewSample-Prefix.pch"; sourceTree = ""; }; 35 | C390E64517474B2400CF3C8F /* PRNDLAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PRNDLAppDelegate.h; sourceTree = ""; }; 36 | C390E64617474B2400CF3C8F /* PRNDLAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PRNDLAppDelegate.m; sourceTree = ""; }; 37 | C390E64817474B2400CF3C8F /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 38 | C390E64A17474B2400CF3C8F /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 39 | C390E64C17474B2400CF3C8F /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 40 | C390E64E17474B2400CF3C8F /* PRNDLMainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PRNDLMainViewController.h; sourceTree = ""; }; 41 | C390E64F17474B2400CF3C8F /* PRNDLMainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PRNDLMainViewController.m; sourceTree = ""; }; 42 | C390E65517474B2400CF3C8F /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/PRNDLMainViewController.xib; sourceTree = ""; }; 43 | C3E6D2821753BCD400B837F9 /* TutorialView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TutorialView.h; path = ../../TutorialView.h; sourceTree = ""; }; 44 | C3E6D2831753BCD400B837F9 /* TutorialView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TutorialView.m; path = ../../TutorialView.m; sourceTree = ""; }; 45 | C3E6D2851753BCF700B837F9 /* Arrow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Arrow.h; path = ../../Arrow.h; sourceTree = ""; }; 46 | C3E6D2861753BCF700B837F9 /* Arrow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Arrow.m; path = ../../Arrow.m; sourceTree = ""; }; 47 | C3F307C11757DB5400F73CEB /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 48 | /* End PBXFileReference section */ 49 | 50 | /* Begin PBXFrameworksBuildPhase section */ 51 | C390E63017474B2400CF3C8F /* Frameworks */ = { 52 | isa = PBXFrameworksBuildPhase; 53 | buildActionMask = 2147483647; 54 | files = ( 55 | C3F307C21757DB5400F73CEB /* QuartzCore.framework in Frameworks */, 56 | C390E63717474B2400CF3C8F /* UIKit.framework in Frameworks */, 57 | C390E63917474B2400CF3C8F /* Foundation.framework in Frameworks */, 58 | C390E63B17474B2400CF3C8F /* CoreGraphics.framework in Frameworks */, 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | C323F161179AEB4000761E75 /* TutorialView */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | C3E6D2821753BCD400B837F9 /* TutorialView.h */, 69 | C3E6D2831753BCD400B837F9 /* TutorialView.m */, 70 | C3E6D2851753BCF700B837F9 /* Arrow.h */, 71 | C3E6D2861753BCF700B837F9 /* Arrow.m */, 72 | ); 73 | name = TutorialView; 74 | sourceTree = ""; 75 | }; 76 | C323F162179AEB5300761E75 /* View Controllers */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | C390E64E17474B2400CF3C8F /* PRNDLMainViewController.h */, 80 | C390E64F17474B2400CF3C8F /* PRNDLMainViewController.m */, 81 | C390E65417474B2400CF3C8F /* PRNDLMainViewController.xib */, 82 | ); 83 | name = "View Controllers"; 84 | sourceTree = ""; 85 | }; 86 | C390E62A17474B2400CF3C8F = { 87 | isa = PBXGroup; 88 | children = ( 89 | C390E63C17474B2400CF3C8F /* TutorialViewSample */, 90 | C390E63517474B2400CF3C8F /* Frameworks */, 91 | C390E63417474B2400CF3C8F /* Products */, 92 | ); 93 | sourceTree = ""; 94 | }; 95 | C390E63417474B2400CF3C8F /* Products */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | C390E63317474B2400CF3C8F /* TutorialViewSample.app */, 99 | ); 100 | name = Products; 101 | sourceTree = ""; 102 | }; 103 | C390E63517474B2400CF3C8F /* Frameworks */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | C3F307C11757DB5400F73CEB /* QuartzCore.framework */, 107 | C390E63617474B2400CF3C8F /* UIKit.framework */, 108 | C390E63817474B2400CF3C8F /* Foundation.framework */, 109 | C390E63A17474B2400CF3C8F /* CoreGraphics.framework */, 110 | ); 111 | name = Frameworks; 112 | sourceTree = ""; 113 | }; 114 | C390E63C17474B2400CF3C8F /* TutorialViewSample */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | C323F161179AEB4000761E75 /* TutorialView */, 118 | C323F162179AEB5300761E75 /* View Controllers */, 119 | C390E64517474B2400CF3C8F /* PRNDLAppDelegate.h */, 120 | C390E64617474B2400CF3C8F /* PRNDLAppDelegate.m */, 121 | C390E63D17474B2400CF3C8F /* Supporting Files */, 122 | ); 123 | path = TutorialViewSample; 124 | sourceTree = ""; 125 | }; 126 | C390E63D17474B2400CF3C8F /* Supporting Files */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | C390E63E17474B2400CF3C8F /* TutorialViewSample-Info.plist */, 130 | C390E63F17474B2400CF3C8F /* InfoPlist.strings */, 131 | C390E64217474B2400CF3C8F /* main.m */, 132 | C390E64417474B2400CF3C8F /* TutorialViewSample-Prefix.pch */, 133 | C390E64817474B2400CF3C8F /* Default.png */, 134 | C390E64A17474B2400CF3C8F /* Default@2x.png */, 135 | C390E64C17474B2400CF3C8F /* Default-568h@2x.png */, 136 | ); 137 | name = "Supporting Files"; 138 | sourceTree = ""; 139 | }; 140 | /* End PBXGroup section */ 141 | 142 | /* Begin PBXNativeTarget section */ 143 | C390E63217474B2400CF3C8F /* TutorialViewSample */ = { 144 | isa = PBXNativeTarget; 145 | buildConfigurationList = C390E65C17474B2400CF3C8F /* Build configuration list for PBXNativeTarget "TutorialViewSample" */; 146 | buildPhases = ( 147 | C390E62F17474B2400CF3C8F /* Sources */, 148 | C390E63017474B2400CF3C8F /* Frameworks */, 149 | C390E63117474B2400CF3C8F /* Resources */, 150 | ); 151 | buildRules = ( 152 | ); 153 | dependencies = ( 154 | ); 155 | name = TutorialViewSample; 156 | productName = TutorialViewSample; 157 | productReference = C390E63317474B2400CF3C8F /* TutorialViewSample.app */; 158 | productType = "com.apple.product-type.application"; 159 | }; 160 | /* End PBXNativeTarget section */ 161 | 162 | /* Begin PBXProject section */ 163 | C390E62B17474B2400CF3C8F /* Project object */ = { 164 | isa = PBXProject; 165 | attributes = { 166 | CLASSPREFIX = PRNDL; 167 | LastUpgradeCheck = 0460; 168 | ORGANIZATIONNAME = "PRNDL Development Studios, LLC"; 169 | }; 170 | buildConfigurationList = C390E62E17474B2400CF3C8F /* Build configuration list for PBXProject "TutorialViewSample" */; 171 | compatibilityVersion = "Xcode 3.2"; 172 | developmentRegion = English; 173 | hasScannedForEncodings = 0; 174 | knownRegions = ( 175 | en, 176 | ); 177 | mainGroup = C390E62A17474B2400CF3C8F; 178 | productRefGroup = C390E63417474B2400CF3C8F /* Products */; 179 | projectDirPath = ""; 180 | projectRoot = ""; 181 | targets = ( 182 | C390E63217474B2400CF3C8F /* TutorialViewSample */, 183 | ); 184 | }; 185 | /* End PBXProject section */ 186 | 187 | /* Begin PBXResourcesBuildPhase section */ 188 | C390E63117474B2400CF3C8F /* Resources */ = { 189 | isa = PBXResourcesBuildPhase; 190 | buildActionMask = 2147483647; 191 | files = ( 192 | C390E64117474B2400CF3C8F /* InfoPlist.strings in Resources */, 193 | C390E64917474B2400CF3C8F /* Default.png in Resources */, 194 | C390E64B17474B2400CF3C8F /* Default@2x.png in Resources */, 195 | C390E64D17474B2400CF3C8F /* Default-568h@2x.png in Resources */, 196 | C390E65617474B2400CF3C8F /* PRNDLMainViewController.xib in Resources */, 197 | ); 198 | runOnlyForDeploymentPostprocessing = 0; 199 | }; 200 | /* End PBXResourcesBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | C390E62F17474B2400CF3C8F /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | C390E64317474B2400CF3C8F /* main.m in Sources */, 208 | C390E64717474B2400CF3C8F /* PRNDLAppDelegate.m in Sources */, 209 | C390E65017474B2400CF3C8F /* PRNDLMainViewController.m in Sources */, 210 | C3E6D2841753BCD400B837F9 /* TutorialView.m in Sources */, 211 | C3E6D2871753BCF700B837F9 /* Arrow.m in Sources */, 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | }; 215 | /* End PBXSourcesBuildPhase section */ 216 | 217 | /* Begin PBXVariantGroup section */ 218 | C390E63F17474B2400CF3C8F /* InfoPlist.strings */ = { 219 | isa = PBXVariantGroup; 220 | children = ( 221 | C390E64017474B2400CF3C8F /* en */, 222 | ); 223 | name = InfoPlist.strings; 224 | sourceTree = ""; 225 | }; 226 | C390E65417474B2400CF3C8F /* PRNDLMainViewController.xib */ = { 227 | isa = PBXVariantGroup; 228 | children = ( 229 | C390E65517474B2400CF3C8F /* en */, 230 | ); 231 | name = PRNDLMainViewController.xib; 232 | sourceTree = ""; 233 | }; 234 | /* End PBXVariantGroup section */ 235 | 236 | /* Begin XCBuildConfiguration section */ 237 | C390E65A17474B2400CF3C8F /* Debug */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | ALWAYS_SEARCH_USER_PATHS = NO; 241 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 242 | CLANG_CXX_LIBRARY = "libc++"; 243 | CLANG_ENABLE_OBJC_ARC = YES; 244 | CLANG_WARN_CONSTANT_CONVERSION = YES; 245 | CLANG_WARN_EMPTY_BODY = YES; 246 | CLANG_WARN_ENUM_CONVERSION = YES; 247 | CLANG_WARN_INT_CONVERSION = YES; 248 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 249 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 250 | COPY_PHASE_STRIP = NO; 251 | GCC_C_LANGUAGE_STANDARD = gnu99; 252 | GCC_DYNAMIC_NO_PIC = NO; 253 | GCC_OPTIMIZATION_LEVEL = 0; 254 | GCC_PREPROCESSOR_DEFINITIONS = ( 255 | "DEBUG=1", 256 | "$(inherited)", 257 | ); 258 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 259 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 260 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 261 | GCC_WARN_UNUSED_VARIABLE = YES; 262 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 263 | ONLY_ACTIVE_ARCH = YES; 264 | SDKROOT = iphoneos; 265 | }; 266 | name = Debug; 267 | }; 268 | C390E65B17474B2400CF3C8F /* Release */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | ALWAYS_SEARCH_USER_PATHS = NO; 272 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 273 | CLANG_CXX_LIBRARY = "libc++"; 274 | CLANG_ENABLE_OBJC_ARC = YES; 275 | CLANG_WARN_CONSTANT_CONVERSION = YES; 276 | CLANG_WARN_EMPTY_BODY = YES; 277 | CLANG_WARN_ENUM_CONVERSION = YES; 278 | CLANG_WARN_INT_CONVERSION = YES; 279 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 280 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 281 | COPY_PHASE_STRIP = YES; 282 | GCC_C_LANGUAGE_STANDARD = gnu99; 283 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 284 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 285 | GCC_WARN_UNUSED_VARIABLE = YES; 286 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 287 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 288 | SDKROOT = iphoneos; 289 | VALIDATE_PRODUCT = YES; 290 | }; 291 | name = Release; 292 | }; 293 | C390E65D17474B2400CF3C8F /* Debug */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 297 | GCC_PREFIX_HEADER = "TutorialViewSample/TutorialViewSample-Prefix.pch"; 298 | INFOPLIST_FILE = "TutorialViewSample/TutorialViewSample-Info.plist"; 299 | PRODUCT_NAME = "$(TARGET_NAME)"; 300 | WRAPPER_EXTENSION = app; 301 | }; 302 | name = Debug; 303 | }; 304 | C390E65E17474B2400CF3C8F /* Release */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 308 | GCC_PREFIX_HEADER = "TutorialViewSample/TutorialViewSample-Prefix.pch"; 309 | INFOPLIST_FILE = "TutorialViewSample/TutorialViewSample-Info.plist"; 310 | PRODUCT_NAME = "$(TARGET_NAME)"; 311 | WRAPPER_EXTENSION = app; 312 | }; 313 | name = Release; 314 | }; 315 | /* End XCBuildConfiguration section */ 316 | 317 | /* Begin XCConfigurationList section */ 318 | C390E62E17474B2400CF3C8F /* Build configuration list for PBXProject "TutorialViewSample" */ = { 319 | isa = XCConfigurationList; 320 | buildConfigurations = ( 321 | C390E65A17474B2400CF3C8F /* Debug */, 322 | C390E65B17474B2400CF3C8F /* Release */, 323 | ); 324 | defaultConfigurationIsVisible = 0; 325 | defaultConfigurationName = Release; 326 | }; 327 | C390E65C17474B2400CF3C8F /* Build configuration list for PBXNativeTarget "TutorialViewSample" */ = { 328 | isa = XCConfigurationList; 329 | buildConfigurations = ( 330 | C390E65D17474B2400CF3C8F /* Debug */, 331 | C390E65E17474B2400CF3C8F /* Release */, 332 | ); 333 | defaultConfigurationIsVisible = 0; 334 | defaultConfigurationName = Release; 335 | }; 336 | /* End XCConfigurationList section */ 337 | }; 338 | rootObject = C390E62B17474B2400CF3C8F /* Project object */; 339 | } 340 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample.xcodeproj/project.xcworkspace/xcshareddata/TutorialViewSample.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | B1BE72DF-BD4A-4FF5-BDEE-501B595FC8B7 9 | IDESourceControlProjectName 10 | TutorialViewSample 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 11FAA9B2-EC66-4C88-9822-E872126C3852 14 | https://github.com/DavidBenko/TutorialView.git 15 | 16 | IDESourceControlProjectPath 17 | iOS/TutorialViewSample/TutorialViewSample.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 11FAA9B2-EC66-4C88-9822-E872126C3852 21 | ../../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/DavidBenko/TutorialView.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 11FAA9B2-EC66-4C88-9822-E872126C3852 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 11FAA9B2-EC66-4C88-9822-E872126C3852 36 | IDESourceControlWCCName 37 | TutorialView 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample.xcodeproj/project.xcworkspace/xcuserdata/davidbenko.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/iOS/TutorialViewSample/TutorialViewSample.xcodeproj/project.xcworkspace/xcuserdata/davidbenko.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample.xcodeproj/xcuserdata/davidbenko.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample.xcodeproj/xcuserdata/davidbenko.xcuserdatad/xcschemes/TutorialViewSample.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 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample.xcodeproj/xcuserdata/davidbenko.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TutorialViewSample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | C390E63217474B2400CF3C8F 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/iOS/TutorialViewSample/TutorialViewSample/.DS_Store -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/iOS/TutorialViewSample/TutorialViewSample/Default-568h@2x.png -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/iOS/TutorialViewSample/TutorialViewSample/Default.png -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidBenko/TutorialView/8372ec958dc3da9ed7e31d0a0c3cef543f10092e/iOS/TutorialViewSample/TutorialViewSample/Default@2x.png -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/PRNDLAppDelegate.h: -------------------------------------------------------------------------------- 1 | //The MIT License (MIT) 2 | // 3 | // 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy 5 | //of this software and associated documentation files (the "Software"), to deal 6 | //in the Software without restriction, including without limitation the rights 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | //copies of the Software, and to permit persons to whom the Software is 9 | //furnished to do so, subject to the following conditions: 10 | // 11 | //The above copyright notice and this permission notice shall be included in 12 | //all copies or substantial portions of the Software. 13 | // 14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | //THE SOFTWARE. 21 | // 22 | //Created By David Benko on 5/15/2013 23 | 24 | #import 25 | 26 | @class PRNDLMainViewController; 27 | 28 | @interface PRNDLAppDelegate : UIResponder 29 | 30 | @property (strong, nonatomic) UIWindow *window; 31 | @property (strong, nonatomic) PRNDLMainViewController *mainViewController; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/PRNDLAppDelegate.m: -------------------------------------------------------------------------------- 1 | //The MIT License (MIT) 2 | // 3 | // 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy 5 | //of this software and associated documentation files (the "Software"), to deal 6 | //in the Software without restriction, including without limitation the rights 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | //copies of the Software, and to permit persons to whom the Software is 9 | //furnished to do so, subject to the following conditions: 10 | // 11 | //The above copyright notice and this permission notice shall be included in 12 | //all copies or substantial portions of the Software. 13 | // 14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | //THE SOFTWARE. 21 | // 22 | //Created By David Benko on 5/15/2013 23 | 24 | #import "PRNDLAppDelegate.h" 25 | #import "PRNDLMainViewController.h" 26 | 27 | @implementation PRNDLAppDelegate 28 | 29 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 30 | { 31 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 32 | // Override point for customization after application launch. 33 | self.mainViewController = [[PRNDLMainViewController alloc] initWithNibName:@"PRNDLMainViewController" bundle:nil]; 34 | self.window.rootViewController = self.mainViewController; 35 | [self.window makeKeyAndVisible]; 36 | return YES; 37 | } 38 | 39 | - (void)applicationWillResignActive:(UIApplication *)application 40 | { 41 | // 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. 42 | // 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. 43 | } 44 | 45 | - (void)applicationDidEnterBackground:(UIApplication *)application 46 | { 47 | // 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. 48 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 49 | } 50 | 51 | - (void)applicationWillEnterForeground:(UIApplication *)application 52 | { 53 | // 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. 54 | } 55 | 56 | - (void)applicationDidBecomeActive:(UIApplication *)application 57 | { 58 | // 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. 59 | } 60 | 61 | - (void)applicationWillTerminate:(UIApplication *)application 62 | { 63 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/PRNDLMainViewController.h: -------------------------------------------------------------------------------- 1 | //The MIT License (MIT) 2 | // 3 | // 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy 5 | //of this software and associated documentation files (the "Software"), to deal 6 | //in the Software without restriction, including without limitation the rights 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | //copies of the Software, and to permit persons to whom the Software is 9 | //furnished to do so, subject to the following conditions: 10 | // 11 | //The above copyright notice and this permission notice shall be included in 12 | //all copies or substantial portions of the Software. 13 | // 14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | //THE SOFTWARE. 21 | // 22 | //Created By David Benko on 5/15/2013 23 | 24 | #import "Arrow.h" 25 | #import "TutorialView.h" 26 | 27 | @interface PRNDLMainViewController : UIViewController 28 | - (IBAction)drawArrow; 29 | @end 30 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/PRNDLMainViewController.m: -------------------------------------------------------------------------------- 1 | //The MIT License (MIT) 2 | // 3 | // 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy 5 | //of this software and associated documentation files (the "Software"), to deal 6 | //in the Software without restriction, including without limitation the rights 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | //copies of the Software, and to permit persons to whom the Software is 9 | //furnished to do so, subject to the following conditions: 10 | // 11 | //The above copyright notice and this permission notice shall be included in 12 | //all copies or substantial portions of the Software. 13 | // 14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | //THE SOFTWARE. 21 | // 22 | //Created By David Benko on 5/15/2013 23 | 24 | #import "PRNDLMainViewController.h" 25 | 26 | @interface PRNDLMainViewController () 27 | @property (nonatomic, strong) TutorialView *tutorialView; 28 | - (void)setupTutorialView; 29 | - (void)setupDrawButton; 30 | @end 31 | 32 | @implementation PRNDLMainViewController 33 | @synthesize tutorialView = _tutorialView; 34 | 35 | #pragma mark - View Setup 36 | 37 | - (void)viewDidLoad 38 | { 39 | [super viewDidLoad]; 40 | [self setupTutorialView]; 41 | } 42 | - (void)setupTutorialView { 43 | self.tutorialView = [[TutorialView alloc]initWithFrame:self.view.bounds]; 44 | self.tutorialView.delegate = self; 45 | [self.view addSubview:self.tutorialView]; 46 | [self setupDrawButton]; 47 | } 48 | - (void)setupDrawButton { 49 | UIButton *drawButton = [[UIButton alloc]initWithFrame:CGRectMake(110 , 420, 100, 30)]; 50 | [drawButton setBackgroundColor:[UIColor whiteColor]]; 51 | [drawButton setTitle:@"Draw" forState:UIControlStateNormal]; 52 | [drawButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 53 | [drawButton addTarget:self action:@selector(drawArrow) forControlEvents:UIControlEventTouchUpInside]; 54 | [self.tutorialView addSubview:drawButton]; 55 | } 56 | 57 | #pragma mark - Arrow 58 | 59 | - (IBAction)drawArrow 60 | { 61 | if(!self.tutorialView)[self setupTutorialView]; 62 | 63 | Arrow *a = [[Arrow alloc]init]; 64 | a.head = CGPointMake(arc4random() % 300, arc4random() % 300); 65 | a.tail = CGPointMake(arc4random() % 300, arc4random() % 300); 66 | a.curved = floorf((arc4random() % 2)); 67 | a.direction = floorf((arc4random() % 2)); 68 | [self.tutorialView addArrow:a]; 69 | } 70 | 71 | #pragma mark - TutorialViewDelegate 72 | 73 | - (BOOL)tutorialView:(TutorialView *)tutorialView shouldDismissAnimated:(bool *)animated{ 74 | //Override TutorialView Dismiss 75 | NSLog(@"TutorialView should dismiss"); 76 | return true; 77 | } 78 | - (void)tutorialView:(TutorialView *)tutorialView didDismissAnimated:(BOOL)animated{ 79 | NSLog(@"TutorialView did dismiss"); 80 | } 81 | - (BOOL)tutorialView:(TutorialView *)tutorialView shouldDrawPath:(CGPathRef)path animated:(BOOL)animated{ 82 | //Override Path Drawing 83 | NSLog(@"TutorialView shouldDrawPath animated=%@", animated ? @"YES" : @"NO"); 84 | return true; 85 | } 86 | - (void)tutorialView:(TutorialView *)tutorialView didDrawPath:(CGPathRef)path { 87 | NSLog(@"TutorialView didDrawPath"); 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/TutorialViewSample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.prndl.tutviewsample.${PRODUCT_NAME:rfc1034identifier} 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 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIStatusBarTintParameters 32 | 33 | UINavigationBar 34 | 35 | Style 36 | UIBarStyleBlack 37 | Translucent 38 | 39 | 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/TutorialViewSample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'TutorialViewSample' target in the 'TutorialViewSample' 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 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/en.lproj/PRNDLMainViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1552 5 | 12E55 6 | 3084 7 | 1187.39 8 | 626.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 2083 12 | 13 | 14 | IBProxyObject 15 | IBUIView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 274 36 | 37 | {{0, 20}, {320, 548}} 38 | 39 | 40 | 41 | 42 | 3 43 | MC4yNQA 44 | 45 | 2 46 | 47 | 48 | NO 49 | 50 | 51 | IBUIScreenMetrics 52 | 53 | YES 54 | 55 | 56 | 57 | 58 | 59 | {320, 568} 60 | {568, 320} 61 | 62 | 63 | IBCocoaTouchFramework 64 | Retina 4 Full Screen 65 | 2 66 | 67 | IBCocoaTouchFramework 68 | 69 | 70 | 71 | 72 | 73 | 74 | view 75 | 76 | 77 | 78 | 35 79 | 80 | 81 | 82 | 83 | 84 | 0 85 | 86 | 87 | 88 | 89 | 90 | -1 91 | 92 | 93 | File's Owner 94 | 95 | 96 | -2 97 | 98 | 99 | 100 | 101 | 34 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | PRNDLMainViewController 110 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 111 | UIResponder 112 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 113 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 114 | 115 | 116 | 117 | 118 | 119 | 45 120 | 121 | 122 | 123 | 124 | PRNDLMainViewController 125 | UIViewController 126 | 127 | id 128 | id 129 | 130 | 131 | 132 | drawArrow 133 | id 134 | 135 | 136 | showInfo: 137 | id 138 | 139 | 140 | 141 | IBProjectSource 142 | ./Classes/PRNDLMainViewController.h 143 | 144 | 145 | 146 | 147 | 0 148 | IBCocoaTouchFramework 149 | YES 150 | 3 151 | YES 152 | 2083 153 | 154 | 155 | -------------------------------------------------------------------------------- /iOS/TutorialViewSample/TutorialViewSample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TutorialViewSample 4 | // 5 | // Created by David Benko on 5/18/13. 6 | // Copyright (c) 2013 PRNDL Development Studios, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "PRNDLAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([PRNDLAppDelegate class])); 17 | } 18 | } 19 | --------------------------------------------------------------------------------