├── .DS_Store ├── EMHint.podspec ├── HintMakerExample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── HintMakerExample.xccheckout │ └── xcuserdata │ │ ├── ericmcconkie.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── mcconkiee.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings └── xcuserdata │ ├── ericmcconkie.xcuserdatad │ └── xcschemes │ │ ├── HintMakerExample.xcscheme │ │ └── xcschememanagement.plist │ └── mcconkiee.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ ├── HintMakerExample.xcscheme │ └── xcschememanagement.plist ├── HintMakerExample ├── EMAppDelegate.h ├── EMAppDelegate.m ├── EMHint.h ├── EMHint.m ├── EMHintsView.h ├── EMHintsView.m ├── EMViewController.h ├── EMViewController.m ├── EMViewController.xib ├── HintHelper.h ├── HintHelper.m ├── HintMakerExample-Info.plist ├── HintMakerExample-Prefix.pch ├── en.lproj │ └── InfoPlist.strings ├── main.m └── sample.png ├── LICENSE.txt └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcconkiee/EMHint/1b65ddb91f8b7359a8d6ec857f06cd33d50c6785/.DS_Store -------------------------------------------------------------------------------- /EMHint.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "EMHint" 3 | s.version = "1.0" 4 | s.summary = "EMHint adds multiple spotlight-like effects to a view hinting at some things that may be important on the screen." 5 | 6 | s.description = "EMHint is an iOS class group that easily adds a spotlight-like effect to a view highlighting or hinting at something that may be important on the screen.The protocols of EMHintDelegate allow users to override many of the default actions and views. Tapping the black overlay fades it away. Great for quick 'how to' or tutorials in your app" 7 | 8 | s.homepage = "https://github.com/mcconkiee/EMHint" 9 | s.license = { :type => 'MIT', :file => 'LICENSE' } 10 | s.author = { "Eric McConkie" => "eric@ericmcconkie.com" } 11 | s.platform = :ios, '6.0' 12 | s.source = { :git => "https://github.com/mcconkiee/EMHint.git",:tag => "1.0"} 13 | s.source_files = 'HintMakerExample' 14 | s.requires_arc = false 15 | end -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A11F3B141513E81000EE2AAD /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11F3B131513E81000EE2AAD /* UIKit.framework */; }; 11 | A11F3B161513E81000EE2AAD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11F3B151513E81000EE2AAD /* Foundation.framework */; }; 12 | A11F3B181513E81000EE2AAD /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11F3B171513E81000EE2AAD /* CoreGraphics.framework */; }; 13 | A11F3B1E1513E81000EE2AAD /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A11F3B1C1513E81000EE2AAD /* InfoPlist.strings */; }; 14 | A11F3B201513E81000EE2AAD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A11F3B1F1513E81000EE2AAD /* main.m */; }; 15 | A11F3B241513E81000EE2AAD /* EMAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A11F3B231513E81000EE2AAD /* EMAppDelegate.m */; }; 16 | A11F3B341513E82C00EE2AAD /* EMHint.m in Sources */ = {isa = PBXBuildFile; fileRef = A11F3B311513E82C00EE2AAD /* EMHint.m */; }; 17 | A11F3B351513E82C00EE2AAD /* EMHintsView.m in Sources */ = {isa = PBXBuildFile; fileRef = A11F3B321513E82C00EE2AAD /* EMHintsView.m */; }; 18 | A11F3B371513E90300EE2AAD /* sample.png in Resources */ = {isa = PBXBuildFile; fileRef = A11F3B361513E90300EE2AAD /* sample.png */; }; 19 | A1FC40A3151F909C00056FF7 /* EMViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A1FC40A0151F909C00056FF7 /* EMViewController.m */; }; 20 | A1FC40A4151F909C00056FF7 /* HintHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = A1FC40A2151F909C00056FF7 /* HintHelper.m */; }; 21 | A1FC40A6151F90C200056FF7 /* EMViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1FC40A5151F90C200056FF7 /* EMViewController.xib */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | A11F3B0F1513E81000EE2AAD /* HintMakerExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HintMakerExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | A11F3B131513E81000EE2AAD /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 27 | A11F3B151513E81000EE2AAD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 28 | A11F3B171513E81000EE2AAD /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 29 | A11F3B1B1513E81000EE2AAD /* HintMakerExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HintMakerExample-Info.plist"; sourceTree = ""; }; 30 | A11F3B1D1513E81000EE2AAD /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 31 | A11F3B1F1513E81000EE2AAD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32 | A11F3B211513E81000EE2AAD /* HintMakerExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HintMakerExample-Prefix.pch"; sourceTree = ""; }; 33 | A11F3B221513E81000EE2AAD /* EMAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EMAppDelegate.h; sourceTree = ""; }; 34 | A11F3B231513E81000EE2AAD /* EMAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EMAppDelegate.m; sourceTree = ""; }; 35 | A11F3B301513E82C00EE2AAD /* EMHint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EMHint.h; sourceTree = ""; }; 36 | A11F3B311513E82C00EE2AAD /* EMHint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EMHint.m; sourceTree = ""; }; 37 | A11F3B321513E82C00EE2AAD /* EMHintsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EMHintsView.m; sourceTree = ""; }; 38 | A11F3B331513E82C00EE2AAD /* EMHintsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EMHintsView.h; sourceTree = ""; }; 39 | A11F3B361513E90300EE2AAD /* sample.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = sample.png; sourceTree = ""; }; 40 | A1FC409F151F909C00056FF7 /* EMViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EMViewController.h; sourceTree = ""; }; 41 | A1FC40A0151F909C00056FF7 /* EMViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EMViewController.m; sourceTree = ""; }; 42 | A1FC40A1151F909C00056FF7 /* HintHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HintHelper.h; sourceTree = ""; }; 43 | A1FC40A2151F909C00056FF7 /* HintHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HintHelper.m; sourceTree = ""; }; 44 | A1FC40A5151F90C200056FF7 /* EMViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EMViewController.xib; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | A11F3B0C1513E81000EE2AAD /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | A11F3B141513E81000EE2AAD /* UIKit.framework in Frameworks */, 53 | A11F3B161513E81000EE2AAD /* Foundation.framework in Frameworks */, 54 | A11F3B181513E81000EE2AAD /* CoreGraphics.framework in Frameworks */, 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | A11F3B041513E81000EE2AAD = { 62 | isa = PBXGroup; 63 | children = ( 64 | A11F3B191513E81000EE2AAD /* HintMakerExample */, 65 | A11F3B121513E81000EE2AAD /* Frameworks */, 66 | A11F3B101513E81000EE2AAD /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | A11F3B101513E81000EE2AAD /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | A11F3B0F1513E81000EE2AAD /* HintMakerExample.app */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | A11F3B121513E81000EE2AAD /* Frameworks */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | A11F3B131513E81000EE2AAD /* UIKit.framework */, 82 | A11F3B151513E81000EE2AAD /* Foundation.framework */, 83 | A11F3B171513E81000EE2AAD /* CoreGraphics.framework */, 84 | ); 85 | name = Frameworks; 86 | sourceTree = ""; 87 | }; 88 | A11F3B191513E81000EE2AAD /* HintMakerExample */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | A11F3B221513E81000EE2AAD /* EMAppDelegate.h */, 92 | A1FC409F151F909C00056FF7 /* EMViewController.h */, 93 | A1FC40A5151F90C200056FF7 /* EMViewController.xib */, 94 | A1FC40A0151F909C00056FF7 /* EMViewController.m */, 95 | A1FC40A1151F909C00056FF7 /* HintHelper.h */, 96 | A1FC40A2151F909C00056FF7 /* HintHelper.m */, 97 | A11F3B231513E81000EE2AAD /* EMAppDelegate.m */, 98 | A11F3B3B151406AE00EE2AAD /* EMHint */, 99 | A11F3B1A1513E81000EE2AAD /* Supporting Files */, 100 | ); 101 | path = HintMakerExample; 102 | sourceTree = ""; 103 | }; 104 | A11F3B1A1513E81000EE2AAD /* Supporting Files */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | A11F3B361513E90300EE2AAD /* sample.png */, 108 | A11F3B1B1513E81000EE2AAD /* HintMakerExample-Info.plist */, 109 | A11F3B1C1513E81000EE2AAD /* InfoPlist.strings */, 110 | A11F3B1F1513E81000EE2AAD /* main.m */, 111 | A11F3B211513E81000EE2AAD /* HintMakerExample-Prefix.pch */, 112 | ); 113 | name = "Supporting Files"; 114 | sourceTree = ""; 115 | }; 116 | A11F3B3B151406AE00EE2AAD /* EMHint */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | A11F3B301513E82C00EE2AAD /* EMHint.h */, 120 | A11F3B311513E82C00EE2AAD /* EMHint.m */, 121 | A11F3B321513E82C00EE2AAD /* EMHintsView.m */, 122 | A11F3B331513E82C00EE2AAD /* EMHintsView.h */, 123 | ); 124 | name = EMHint; 125 | sourceTree = ""; 126 | }; 127 | /* End PBXGroup section */ 128 | 129 | /* Begin PBXNativeTarget section */ 130 | A11F3B0E1513E81000EE2AAD /* HintMakerExample */ = { 131 | isa = PBXNativeTarget; 132 | buildConfigurationList = A11F3B2D1513E81000EE2AAD /* Build configuration list for PBXNativeTarget "HintMakerExample" */; 133 | buildPhases = ( 134 | A11F3B0B1513E81000EE2AAD /* Sources */, 135 | A11F3B0C1513E81000EE2AAD /* Frameworks */, 136 | A11F3B0D1513E81000EE2AAD /* Resources */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | ); 142 | name = HintMakerExample; 143 | productName = HintMakerExample; 144 | productReference = A11F3B0F1513E81000EE2AAD /* HintMakerExample.app */; 145 | productType = "com.apple.product-type.application"; 146 | }; 147 | /* End PBXNativeTarget section */ 148 | 149 | /* Begin PBXProject section */ 150 | A11F3B061513E81000EE2AAD /* Project object */ = { 151 | isa = PBXProject; 152 | attributes = { 153 | LastUpgradeCheck = 0420; 154 | }; 155 | buildConfigurationList = A11F3B091513E81000EE2AAD /* Build configuration list for PBXProject "HintMakerExample" */; 156 | compatibilityVersion = "Xcode 3.2"; 157 | developmentRegion = English; 158 | hasScannedForEncodings = 0; 159 | knownRegions = ( 160 | en, 161 | ); 162 | mainGroup = A11F3B041513E81000EE2AAD; 163 | productRefGroup = A11F3B101513E81000EE2AAD /* Products */; 164 | projectDirPath = ""; 165 | projectRoot = ""; 166 | targets = ( 167 | A11F3B0E1513E81000EE2AAD /* HintMakerExample */, 168 | ); 169 | }; 170 | /* End PBXProject section */ 171 | 172 | /* Begin PBXResourcesBuildPhase section */ 173 | A11F3B0D1513E81000EE2AAD /* Resources */ = { 174 | isa = PBXResourcesBuildPhase; 175 | buildActionMask = 2147483647; 176 | files = ( 177 | A11F3B1E1513E81000EE2AAD /* InfoPlist.strings in Resources */, 178 | A11F3B371513E90300EE2AAD /* sample.png in Resources */, 179 | A1FC40A6151F90C200056FF7 /* EMViewController.xib in Resources */, 180 | ); 181 | runOnlyForDeploymentPostprocessing = 0; 182 | }; 183 | /* End PBXResourcesBuildPhase section */ 184 | 185 | /* Begin PBXSourcesBuildPhase section */ 186 | A11F3B0B1513E81000EE2AAD /* Sources */ = { 187 | isa = PBXSourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | A11F3B201513E81000EE2AAD /* main.m in Sources */, 191 | A11F3B241513E81000EE2AAD /* EMAppDelegate.m in Sources */, 192 | A11F3B341513E82C00EE2AAD /* EMHint.m in Sources */, 193 | A11F3B351513E82C00EE2AAD /* EMHintsView.m in Sources */, 194 | A1FC40A3151F909C00056FF7 /* EMViewController.m in Sources */, 195 | A1FC40A4151F909C00056FF7 /* HintHelper.m in Sources */, 196 | ); 197 | runOnlyForDeploymentPostprocessing = 0; 198 | }; 199 | /* End PBXSourcesBuildPhase section */ 200 | 201 | /* Begin PBXVariantGroup section */ 202 | A11F3B1C1513E81000EE2AAD /* InfoPlist.strings */ = { 203 | isa = PBXVariantGroup; 204 | children = ( 205 | A11F3B1D1513E81000EE2AAD /* en */, 206 | ); 207 | name = InfoPlist.strings; 208 | sourceTree = ""; 209 | }; 210 | /* End PBXVariantGroup section */ 211 | 212 | /* Begin XCBuildConfiguration section */ 213 | A11F3B2B1513E81000EE2AAD /* Debug */ = { 214 | isa = XCBuildConfiguration; 215 | buildSettings = { 216 | ALWAYS_SEARCH_USER_PATHS = NO; 217 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 218 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 219 | COPY_PHASE_STRIP = NO; 220 | GCC_C_LANGUAGE_STANDARD = gnu99; 221 | GCC_DYNAMIC_NO_PIC = NO; 222 | GCC_OPTIMIZATION_LEVEL = 0; 223 | GCC_PREPROCESSOR_DEFINITIONS = ( 224 | "DEBUG=1", 225 | "$(inherited)", 226 | ); 227 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 228 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 229 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 230 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 231 | GCC_WARN_UNUSED_VARIABLE = YES; 232 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 233 | SDKROOT = iphoneos; 234 | }; 235 | name = Debug; 236 | }; 237 | A11F3B2C1513E81000EE2AAD /* Release */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | ALWAYS_SEARCH_USER_PATHS = NO; 241 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 242 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 243 | COPY_PHASE_STRIP = YES; 244 | GCC_C_LANGUAGE_STANDARD = gnu99; 245 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 246 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 247 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 248 | GCC_WARN_UNUSED_VARIABLE = YES; 249 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 250 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 251 | SDKROOT = iphoneos; 252 | VALIDATE_PRODUCT = YES; 253 | }; 254 | name = Release; 255 | }; 256 | A11F3B2E1513E81000EE2AAD /* Debug */ = { 257 | isa = XCBuildConfiguration; 258 | buildSettings = { 259 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 260 | GCC_PREFIX_HEADER = "HintMakerExample/HintMakerExample-Prefix.pch"; 261 | INFOPLIST_FILE = "HintMakerExample/HintMakerExample-Info.plist"; 262 | PRODUCT_NAME = "$(TARGET_NAME)"; 263 | WRAPPER_EXTENSION = app; 264 | }; 265 | name = Debug; 266 | }; 267 | A11F3B2F1513E81000EE2AAD /* Release */ = { 268 | isa = XCBuildConfiguration; 269 | buildSettings = { 270 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 271 | GCC_PREFIX_HEADER = "HintMakerExample/HintMakerExample-Prefix.pch"; 272 | INFOPLIST_FILE = "HintMakerExample/HintMakerExample-Info.plist"; 273 | PRODUCT_NAME = "$(TARGET_NAME)"; 274 | WRAPPER_EXTENSION = app; 275 | }; 276 | name = Release; 277 | }; 278 | /* End XCBuildConfiguration section */ 279 | 280 | /* Begin XCConfigurationList section */ 281 | A11F3B091513E81000EE2AAD /* Build configuration list for PBXProject "HintMakerExample" */ = { 282 | isa = XCConfigurationList; 283 | buildConfigurations = ( 284 | A11F3B2B1513E81000EE2AAD /* Debug */, 285 | A11F3B2C1513E81000EE2AAD /* Release */, 286 | ); 287 | defaultConfigurationIsVisible = 0; 288 | defaultConfigurationName = Release; 289 | }; 290 | A11F3B2D1513E81000EE2AAD /* Build configuration list for PBXNativeTarget "HintMakerExample" */ = { 291 | isa = XCConfigurationList; 292 | buildConfigurations = ( 293 | A11F3B2E1513E81000EE2AAD /* Debug */, 294 | A11F3B2F1513E81000EE2AAD /* Release */, 295 | ); 296 | defaultConfigurationIsVisible = 0; 297 | defaultConfigurationName = Release; 298 | }; 299 | /* End XCConfigurationList section */ 300 | }; 301 | rootObject = A11F3B061513E81000EE2AAD /* Project object */; 302 | } 303 | -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/project.xcworkspace/xcshareddata/HintMakerExample.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 6ADEE4AD-326C-46E7-9234-68E460D7F134 9 | IDESourceControlProjectName 10 | HintMakerExample 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 550A8B12-79E0-446A-808D-8CDBD6C87783 14 | https://github.com/mcconkiee/EMHint.git 15 | 16 | IDESourceControlProjectPath 17 | HintMakerExample.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 550A8B12-79E0-446A-808D-8CDBD6C87783 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/mcconkiee/EMHint.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 550A8B12-79E0-446A-808D-8CDBD6C87783 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 550A8B12-79E0-446A-808D-8CDBD6C87783 36 | IDESourceControlWCCName 37 | EMHint 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/project.xcworkspace/xcuserdata/ericmcconkie.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcconkiee/EMHint/1b65ddb91f8b7359a8d6ec857f06cd33d50c6785/HintMakerExample.xcodeproj/project.xcworkspace/xcuserdata/ericmcconkie.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/project.xcworkspace/xcuserdata/mcconkiee.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcconkiee/EMHint/1b65ddb91f8b7359a8d6ec857f06cd33d50c6785/HintMakerExample.xcodeproj/project.xcworkspace/xcuserdata/mcconkiee.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/project.xcworkspace/xcuserdata/mcconkiee.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/xcuserdata/ericmcconkie.xcuserdatad/xcschemes/HintMakerExample.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 | -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/xcuserdata/ericmcconkie.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HintMakerExample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | A11F3B0E1513E81000EE2AAD 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/xcuserdata/mcconkiee.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/xcuserdata/mcconkiee.xcuserdatad/xcschemes/HintMakerExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 14 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 38 | 39 | 40 | 41 | 49 | 50 | 56 | 57 | 58 | 59 | 63 | 64 | 65 | 66 | 72 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /HintMakerExample.xcodeproj/xcuserdata/mcconkiee.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HintMakerExample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | A11F3B0E1513E81000EE2AAD 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /HintMakerExample/EMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMAppDelegate.h 3 | // HintMakerExample 4 | // 5 | // Created by Eric McConkie on 3/16/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import 17 | #import "HintHelper.h" 18 | @class EMViewController; 19 | 20 | @interface EMAppDelegate : UIResponder 21 | { 22 | HintHelper *_hintHelper; 23 | } 24 | @property (strong, nonatomic) UIWindow *window; 25 | 26 | @property (strong, nonatomic) EMViewController *viewController; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /HintMakerExample/EMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMAppDelegate.m 3 | // HintMakerExample 4 | // 5 | // Created by Eric McConkie on 3/16/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import "EMAppDelegate.h" 17 | #import "EMViewController.h" 18 | 19 | @implementation EMAppDelegate 20 | 21 | @synthesize window = _window; 22 | @synthesize viewController = _viewController; 23 | 24 | - (void)dealloc 25 | { 26 | [_window release]; 27 | [_viewController release]; 28 | [super dealloc]; 29 | } 30 | 31 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 32 | { 33 | self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 34 | // Override point for customization after application launch. 35 | self.viewController = [[[EMViewController alloc] initWithNibName:@"EMViewController" bundle:nil] autorelease]; 36 | 37 | UIViewController *test = [[UIViewController alloc] init]; 38 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:test]; 39 | [test release]; 40 | [nav pushViewController:self.viewController animated:YES]; 41 | 42 | 43 | //add a hint helper to control the chain of hints , messaging, etc 44 | _hintHelper = [[HintHelper alloc] initWithViewController:self.viewController]; 45 | 46 | 47 | self.window.rootViewController = nav; 48 | [nav release]; 49 | [self.window makeKeyAndVisible]; 50 | return YES; 51 | } 52 | 53 | - (void)applicationWillResignActive:(UIApplication *)application 54 | { 55 | /* 56 | 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. 57 | 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. 58 | */ 59 | } 60 | 61 | - (void)applicationDidEnterBackground:(UIApplication *)application 62 | { 63 | /* 64 | 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. 65 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 66 | */ 67 | } 68 | 69 | - (void)applicationWillEnterForeground:(UIApplication *)application 70 | { 71 | /* 72 | 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. 73 | */ 74 | } 75 | 76 | - (void)applicationDidBecomeActive:(UIApplication *)application 77 | { 78 | /* 79 | 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. 80 | */ 81 | } 82 | 83 | - (void)applicationWillTerminate:(UIApplication *)application 84 | { 85 | /* 86 | Called when the application is about to terminate. 87 | Save data if appropriate. 88 | See also applicationDidEnterBackground:. 89 | */ 90 | } 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /HintMakerExample/EMHint.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMHintState.h 3 | // ModalStateOverviewTest 4 | // 5 | // Created by Eric McConkie on 3/6/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import 17 | #import "EMHintsView.h" 18 | 19 | typedef enum 20 | { 21 | EMHintShapeTypeRound, 22 | EMHintShapeTypeRectangle//TODO 23 | }EMHintShapeType; 24 | 25 | @protocol EMHintDelegate 26 | 27 | @optional 28 | 29 | -(BOOL)hintStateHasDefaultTapGestureRecognizer:(id)hintState ; 30 | 31 | 32 | 33 | /* 34 | // return an array of UIView where spotlights should shine 35 | */ 36 | -(NSArray*)hintStateViewsToHint:(id)hintState; 37 | 38 | /* 39 | // the default hint space is a label with white helvetica text dynamically centered, 40 | // one can return a custom view here to override that label 41 | */ 42 | -(UIView*)hintStateViewForDialog:(id)hintState; 43 | 44 | /* 45 | // return an array of rects (NSValue objs) for where spotlights should shine. 46 | // convenient if UIView array is not an option 47 | */ 48 | -(NSArray*)hintStateRectsToHint:(id)hintState; 49 | 50 | /* 51 | // return NO, if you plan to daisy chain hints, or do someother action 52 | // return YES, to fad out modal hint view 53 | */ 54 | -(BOOL) hintStateShouldCloseIfPermitted:(id)hintState ; 55 | 56 | /* 57 | // called just before the close (fade) of a modal state view 58 | */ 59 | -(void) hintStateWillClose:(id)hintState ; 60 | 61 | /* 62 | // called immediately after the modal hint view has faded to zero alpha and is removed 63 | */ 64 | -(void) hintStateDidClose:(id)hintState ; 65 | 66 | 67 | 68 | 69 | 70 | /* 71 | // Default hint is a round spotlight effect, 72 | // TODO:// rectangle type can be returned to override 73 | */ 74 | //-(EMHintShapeType)hintStateShapeType:(id)hintState; 75 | 76 | 77 | @end 78 | 79 | @interface EMHint : NSObject 80 | { 81 | EMHintsView *_modalView;//our transparent hint window with lablel and spotlight 82 | } 83 | @property (nonatomic,assign) id hintDelegate; 84 | 85 | -(UIView*)modalView; // accessor to the modal view (use spareingly) 86 | -(void)clear;//instant removal of modal view 87 | 88 | /* 89 | //initiates the modal hint view 90 | //default is a spotlight effect on the UIView or Rect returned from one of the protocol methods 91 | // message is the message in the label 92 | // where is the view onto which the modal will overlay 93 | */ 94 | -(void)presentModalMessage:(NSString*)message where:(UIView*)presentationPlace; 95 | @end 96 | -------------------------------------------------------------------------------- /HintMakerExample/EMHint.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMHintState.m 3 | // ModalStateOverviewTest 4 | // 5 | // Created by Eric McConkie on 3/6/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import "EMHint.h" 17 | 18 | @implementation EMHint 19 | @synthesize hintDelegate; 20 | 21 | #pragma mark ---------------------------------->> 22 | #pragma mark -------------->>private 23 | -(void)_onTap:(UITapGestureRecognizer*)tap 24 | { 25 | BOOL flag = YES; 26 | if ([self.hintDelegate respondsToSelector:@selector(hintStateShouldCloseIfPermitted:)]) { 27 | flag = [self.hintDelegate hintStateShouldCloseIfPermitted:self]; 28 | } 29 | if(!flag)return; 30 | if ([self.hintDelegate respondsToSelector:@selector(hintStateWillClose:)]) { 31 | [self.hintDelegate hintStateWillClose:self]; 32 | } 33 | 34 | [UIView animateWithDuration:0.6 delay:0.0 options:UIViewAnimationOptionCurveEaseOut 35 | animations:^(){ 36 | [_modalView setAlpha:0.0]; 37 | } 38 | completion:^(BOOL finished){ 39 | [_modalView removeFromSuperview]; 40 | _modalView = nil; 41 | if ([self.hintDelegate respondsToSelector:@selector(hintStateDidClose:)]) 42 | { 43 | [self.hintDelegate hintStateDidClose:self]; 44 | } 45 | 46 | }]; 47 | 48 | } 49 | 50 | -(void)_addTap 51 | { 52 | UITapGestureRecognizer *tap = tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_onTap:)]; 53 | [_modalView addGestureRecognizer:tap]; 54 | [tap release]; 55 | } 56 | 57 | #pragma mark ---------------------------------->> 58 | #pragma mark -------------->>PUBLIC 59 | -(void)clear 60 | { 61 | [_modalView removeFromSuperview]; 62 | _modalView = nil; 63 | } 64 | -(UIView*)modalView 65 | { 66 | return _modalView; 67 | } 68 | -(void)presentModalMessage:(NSString*)message where:(UIView*)presentationPlace 69 | { 70 | //incase we have many in a row 71 | if(_modalView!=nil) 72 | [self clear]; 73 | 74 | if ([self.hintDelegate respondsToSelector:@selector(hintStateViewsToHint:)]) { 75 | NSArray *viewArray = [self.hintDelegate hintStateViewsToHint:self]; 76 | if(viewArray!=nil) 77 | _modalView = [[EMHintsView alloc] initWithFrame:presentationPlace.frame forViews:viewArray]; 78 | } 79 | 80 | if ([self.hintDelegate respondsToSelector:@selector(hintStateRectsToHint:)]) { 81 | NSArray* rectArray = [self.hintDelegate hintStateRectsToHint:self]; 82 | if (rectArray != nil) 83 | _modalView = [[EMHintsView alloc] initWithFrame:presentationPlace.frame withRects:rectArray]; 84 | } 85 | 86 | if (_modalView==nil) 87 | _modalView = [[EMHintsView alloc] initWithFrame:presentationPlace.frame]; 88 | 89 | [_modalView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; 90 | [presentationPlace addSubview:_modalView]; 91 | 92 | UIView *v = nil; 93 | if ([[self hintDelegate] respondsToSelector:@selector(hintStateViewForDialog:)]) { 94 | v = [self.hintDelegate hintStateViewForDialog:self]; 95 | [_modalView addSubview:v]; 96 | } 97 | 98 | if(v==nil)//no custom subview 99 | { 100 | //label 101 | UIFont *ft = [UIFont fontWithName:@"Helvetica" size:17.0]; 102 | CGSize sz = [message sizeWithFont:ft constrainedToSize:CGSizeMake(250, 1000)]; 103 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(floorf(presentationPlace.center.x - sz.width/2), 104 | floorf(presentationPlace.center.y - sz.height/2), 105 | floorf(sz.width), 106 | floorf(sz.height +10 107 | ))]; 108 | 109 | [label setAutoresizingMask:(UIViewAutoresizingFlexibleTopMargin 110 | | UIViewAutoresizingFlexibleRightMargin 111 | | UIViewAutoresizingFlexibleLeftMargin 112 | | UIViewAutoresizingFlexibleBottomMargin 113 | )]; 114 | [label setBackgroundColor:[UIColor clearColor]]; 115 | [label setFont:ft]; 116 | [label setText:message]; 117 | [label setTextColor:[UIColor whiteColor]]; 118 | [label setNumberOfLines:0]; 119 | [label setLineBreakMode:UILineBreakModeWordWrap]; 120 | [_modalView addSubview:label]; 121 | [label release]; 122 | } 123 | 124 | if ([[self hintDelegate] respondsToSelector:@selector(hintStateHasDefaultTapGestureRecognizer:)]) { 125 | BOOL flag = [self.hintDelegate hintStateHasDefaultTapGestureRecognizer:self]; 126 | if (flag) { 127 | [self _addTap]; 128 | } 129 | }else 130 | { 131 | [self _addTap]; 132 | } 133 | 134 | 135 | } 136 | #pragma mark ---------------------------------->> 137 | #pragma mark -------------->>cleanup 138 | - (void)dealloc { 139 | [_modalView release]; 140 | [super dealloc]; 141 | } 142 | @end 143 | -------------------------------------------------------------------------------- /HintMakerExample/EMHintsView.h: -------------------------------------------------------------------------------- 1 | // 2 | // EMHintView.h 3 | // ModalStateOverviewTest 4 | // 5 | // Created by Eric McConkie on 3/6/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import 17 | 18 | @interface EMHintsView : UIView 19 | { 20 | // array positions of spotlights 21 | NSMutableArray* _positionArray; 22 | // array radius of spotlights 23 | NSMutableArray* _radiusArray; 24 | } 25 | 26 | - (id)initWithFrame:(CGRect)frame; 27 | - (id)initWithFrame:(CGRect)frame forViews:(NSArray*)viewArray; 28 | - (id)initWithFrame:(CGRect)frame withRects:(NSArray*)rectArray; 29 | @end 30 | -------------------------------------------------------------------------------- /HintMakerExample/EMHintsView.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMHintView.m 3 | // ModalStateOverviewTest 4 | // 5 | // Created by Eric McConkie on 3/6/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import "EMHintsView.h" 17 | #import 18 | 19 | #define BACKGROUND_ALPHA 0.70 20 | 21 | @implementation EMHintsView 22 | 23 | - (id)initWithFrame:(CGRect)frame 24 | { 25 | self = [super initWithFrame:frame]; 26 | if (self) { 27 | // initialize arrays 28 | _positionArray = [[NSMutableArray alloc] init]; 29 | _radiusArray = [[NSMutableArray alloc] init]; 30 | 31 | // set background color 32 | [self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:BACKGROUND_ALPHA]]; 33 | } 34 | return self; 35 | } 36 | 37 | - (id)initWithFrame:(CGRect)frame withRects:(NSArray *)rectArray 38 | { 39 | self = [super initWithFrame:frame]; 40 | if (self) { 41 | _positionArray = [[NSMutableArray alloc] init]; 42 | _radiusArray = [[NSMutableArray alloc] init]; 43 | // add spotlight position and radius 44 | for (NSValue* theRectObj in rectArray) 45 | { 46 | CGRect theRect = [theRectObj CGRectValue]; 47 | CGPoint pos = CGPointMake(theRect.origin.x, theRect.origin.y); 48 | CGFloat radius = theRect.size.width; 49 | [_positionArray addObject:[NSValue valueWithCGPoint:pos]]; 50 | [_radiusArray addObject:[NSNumber numberWithFloat:radius]]; 51 | } 52 | [self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:BACKGROUND_ALPHA]]; 53 | } 54 | return self; 55 | } 56 | 57 | - (id)initWithFrame:(CGRect)frame forViews:(NSArray *)viewArray 58 | { 59 | self = [super initWithFrame:frame]; 60 | if (self) { 61 | // Initialization code 62 | _positionArray = [[NSMutableArray alloc] init]; 63 | _radiusArray = [[NSMutableArray alloc] init]; 64 | // add spotlight position and radius 65 | for (UIView* theView in viewArray) 66 | { 67 | CGPoint pos = CGPointMake(theView.frame.origin.x + (theView.frame.size.width/2) 68 | , theView.frame.origin.y + (theView.frame.size.height/2) ); 69 | CGFloat radius = theView.frame.size.width; 70 | [_positionArray addObject:[NSValue valueWithCGPoint:pos]]; 71 | [_radiusArray addObject:[NSNumber numberWithFloat:radius]]; 72 | } 73 | 74 | [self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:BACKGROUND_ALPHA]]; 75 | } 76 | return self; 77 | } 78 | 79 | -(void)_background:(CGRect)rect 80 | { 81 | // context for drawing 82 | CGContextRef context = UIGraphicsGetCurrentContext(); 83 | 84 | CGImageRef backgroundimage = CGBitmapContextCreateImage(context); 85 | CGContextClearRect(context, rect); 86 | //CGContextDrawImage(context, rect, backgroundimage); 87 | 88 | // save state 89 | CGContextSaveGState(context); 90 | 91 | // flip the context (right-sideup) 92 | CGContextTranslateCTM(context, 0, rect.size.height); 93 | CGContextScaleCTM(context, 1.0, -1.0); 94 | 95 | //colors/components/locations 96 | CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 97 | CGFloat black[4] = {0.0,0.0,0.0,BACKGROUND_ALPHA}; 98 | CGFloat white[4] = {1.0,1.0,1.0,1.0};//clear 99 | 100 | CGFloat components[8] = { 101 | 102 | white[0],white[1],white[2],white[3], 103 | black[0],black[1],black[2],black[3], 104 | }; 105 | 106 | CGFloat colorLocations[2] = {0.25,0.5}; 107 | 108 | // draw spotlights 109 | int spotlightCount = _positionArray.count; 110 | for (int i=0; i 17 | #import "EMHint.h" 18 | 19 | 20 | @interface EMViewController : UIViewController 21 | { 22 | EMHint *_hint; 23 | id _info; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /HintMakerExample/EMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // EMViewController.m 3 | // HintMakerExample 4 | // 5 | // Created by Eric McConkie on 3/16/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import "EMViewController.h" 17 | 18 | @implementation EMViewController 19 | #pragma mark ---------------------------------->> 20 | #pragma mark -------------->>hint deleage 21 | 22 | -(NSArray*)hintStateViewsToHint:(id)hintState 23 | { 24 | return [[NSArray alloc] initWithObjects:_info, nil]; 25 | } 26 | -(UIView*)hintStateViewForDialog:(id)hintState 27 | { 28 | UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 200, 50)]; 29 | 30 | [l setBackgroundColor:[UIColor clearColor]]; 31 | [l setTextColor:[UIColor whiteColor]]; 32 | [l setText:@"I am the info button!"]; 33 | return l; 34 | } 35 | #pragma mark ---------------------------------->> 36 | #pragma mark -------------->>private 37 | -(void)_onTap:(id)sender 38 | { 39 | [_hint presentModalMessage:@"One last hint for ya." where:self.view]; 40 | } 41 | #pragma mark - View lifecycle 42 | 43 | -(void)_ui 44 | { 45 | 46 | 47 | UIButton *bt2 = [UIButton buttonWithType:UIButtonTypeInfoDark]; 48 | [bt2 setCenter:self.view.center]; 49 | [bt2 addTarget:self action:@selector(_onTap:) forControlEvents:UIControlEventTouchUpInside]; 50 | _info =bt2; 51 | [self.view addSubview:bt2]; 52 | 53 | 54 | UIBarButtonItem *bi = [[UIBarButtonItem alloc] initWithTitle:@"list" style:UIBarButtonItemStyleBordered target:nil action:nil]; 55 | [self.navigationItem setRightBarButtonItem:bi]; 56 | [bi release]; 57 | } 58 | - (void)viewWillAppear:(BOOL)animated 59 | { 60 | [super viewWillAppear:animated]; 61 | [self _ui]; 62 | 63 | _hint = [[EMHint alloc] init]; 64 | [_hint setHintDelegate:self]; 65 | 66 | } 67 | -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 68 | { 69 | return YES; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /HintMakerExample/EMViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1280 5 | 11C25 6 | 1919 7 | 1138.11 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 916 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 | {{0, 20}, {320, 460}} 37 | 38 | 39 | 40 | 3 41 | MC43NQA 42 | 43 | 2 44 | 45 | 46 | NO 47 | 48 | IBCocoaTouchFramework 49 | 50 | 51 | 52 | 53 | 54 | 55 | view 56 | 57 | 58 | 59 | 7 60 | 61 | 62 | 63 | 64 | 65 | 0 66 | 67 | 68 | 69 | 70 | 71 | -1 72 | 73 | 74 | File's Owner 75 | 76 | 77 | -2 78 | 79 | 80 | 81 | 82 | 6 83 | 84 | 85 | 86 | 87 | 88 | 89 | EMViewController 90 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 91 | UIResponder 92 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 93 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 94 | 95 | 96 | 97 | 98 | 99 | 7 100 | 101 | 102 | 103 | 104 | EMViewController 105 | UIViewController 106 | 107 | IBProjectSource 108 | ./Classes/EMViewController.h 109 | 110 | 111 | 112 | 113 | 0 114 | IBCocoaTouchFramework 115 | YES 116 | 3 117 | 916 118 | 119 | 120 | -------------------------------------------------------------------------------- /HintMakerExample/HintHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // HintHelper.h 3 | // HintMakerExample 4 | // 5 | // Created by Eric McConkie on 3/16/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import 17 | #import "EMHint.h" 18 | #import "EMViewController.h" 19 | #define kFirstMessage @"Spotlights to help lead your users...Tap along." 20 | typedef enum 21 | { 22 | EMHintDialogTypeIntro, 23 | EMHintDialogTypeInfo, 24 | EMHintDialogTypeButton, 25 | EMHintDialogTypeList, 26 | EMHintDialogTypeBack, 27 | EMHintDialogTypeListAndBack, 28 | EMHintDialogTypeCount 29 | }EMHintDialogType; 30 | 31 | 32 | @interface HintHelper : NSObject 33 | { 34 | EMHintDialogType _curType; 35 | EMHint *modalState; 36 | UIViewController *_vc; 37 | } 38 | - (id)initWithViewController:(UIViewController*)vc; 39 | @end 40 | -------------------------------------------------------------------------------- /HintMakerExample/HintHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // HintHelper.m 3 | // HintMakerExample 4 | // 5 | // Created by Eric McConkie on 3/16/12. 6 | /* 7 | Copyright (c) 2012 Eric McConkie 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | #import "HintHelper.h" 17 | 18 | @implementation HintHelper 19 | #pragma mark ---------------------------------->> 20 | #pragma mark -------------->>modal delegate 21 | -(void)doNext 22 | { 23 | switch (_curType) { 24 | case EMHintDialogTypeInfo: 25 | [modalState presentModalMessage:@"Info button! \r\nProtocol: returned rect" where:_vc.navigationController.view]; 26 | break; 27 | case EMHintDialogTypeButton: 28 | [modalState presentModalMessage:@"Here is a simpl black overlay without a spotlight. \r\nProtocol: returned rect" where:_vc.navigationController.view]; 29 | break; 30 | case EMHintDialogTypeList: 31 | [modalState presentModalMessage:@"This is a list button! \r\nProtocol: returned rect" where:_vc.navigationController.view]; 32 | break; 33 | case EMHintDialogTypeListAndBack: 34 | [modalState presentModalMessage:@"Multiple spotlights: list and back button \r\nProtocol: returned rect" where:_vc.navigationController.view]; 35 | break; 36 | default: 37 | [modalState presentModalMessage:@"" where:_vc.navigationController.view]; 38 | break; 39 | } 40 | } 41 | 42 | #pragma mark ---------------------------------->> 43 | #pragma mark -------------->>HInt Delegate 44 | -(BOOL)hintStateShouldCloseIfPermitted:(id)hintState 45 | { 46 | _curType ++; 47 | 48 | if(_curType>=EMHintDialogTypeCount) 49 | { 50 | _curType = 0;//reset for next time 51 | return YES; 52 | } 53 | [self doNext]; 54 | return NO; 55 | } 56 | -(void)hintStateWillClose:(id)hintState 57 | { 58 | NSLog(@"i am about to close: %@",hintState); 59 | } 60 | -(void)hintStateDidClose:(id)hintState 61 | { 62 | NSLog(@"i closed: %@",hintState); 63 | } 64 | 65 | 66 | 67 | 68 | -(NSArray*)hintStateRectsToHint:(id)hintState 69 | { 70 | CGFloat ht = 50.0; 71 | CGFloat statusBarHt = 20.0; 72 | NSArray* rectArray = nil; 73 | switch (_curType) { 74 | case EMHintDialogTypeInfo: 75 | { 76 | CGRect rect = CGRectMake(_vc.view.frame.size.width/2 , 77 | _vc.view.frame.size.height/2 + (statusBarHt + 44), 78 | ht,ht); 79 | rectArray = [[NSArray alloc] initWithObjects:[NSValue valueWithCGRect:rect], nil]; 80 | } 81 | break; 82 | case EMHintDialogTypeList: 83 | { 84 | CGRect rect = CGRectMake(290, ht/2 + statusBarHt,ht,ht); 85 | rectArray = [[NSArray alloc] initWithObjects:[NSValue valueWithCGRect:rect], nil]; 86 | } 87 | break; 88 | case EMHintDialogTypeBack: 89 | { 90 | CGRect rect= CGRectMake(25, ht/2 + statusBarHt,ht,ht); 91 | rectArray = [[NSArray alloc] initWithObjects:[NSValue valueWithCGRect:rect], nil]; 92 | } 93 | break; 94 | case EMHintDialogTypeListAndBack: 95 | { 96 | CGRect backRect = CGRectMake(25, ht/2 + statusBarHt,ht,ht); 97 | CGRect listRect = CGRectMake(290, ht/2 + statusBarHt,ht,ht); 98 | rectArray = [[NSArray alloc] initWithObjects:[NSValue valueWithCGRect:backRect], [NSValue valueWithCGRect:listRect], nil]; 99 | } 100 | break; 101 | 102 | case EMHintDialogTypeButton: 103 | break; 104 | default: 105 | break; 106 | } 107 | return rectArray; 108 | } 109 | 110 | 111 | -(UIView*)hintStateViewForDialog:(id)hintState 112 | { 113 | if (_curType == EMHintDialogTypeBack) { 114 | //label 115 | NSString *icon = @"\u267C"; 116 | UIFont *ft = [UIFont fontWithName:@"Arial" size:150.0]; 117 | CGSize sz = [icon sizeWithFont:ft constrainedToSize:CGSizeMake(250, 1000)]; 118 | UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(floorf(_vc.view.center.x - sz.width/2), 119 | _vc.view.center.y - sz.height/2, 120 | floorf(sz.width), 121 | floorf(sz.height +10 122 | ))] autorelease]; 123 | [label setBackgroundColor:[UIColor clearColor]]; 124 | [label setTextAlignment:UITextAlignmentCenter]; 125 | [label setFont:ft]; 126 | [label setTextColor:[UIColor greenColor]]; 127 | [label setText:icon];//icon 128 | [label setNumberOfLines:0]; 129 | [label setLineBreakMode:UILineBreakModeWordWrap]; 130 | 131 | return label; 132 | } 133 | return nil; 134 | } 135 | - (id)initWithViewController:(UIViewController*)vc { 136 | self = [super init]; 137 | if (self) { 138 | _vc = vc; 139 | _curType = EMHintDialogTypeIntro; 140 | 141 | // Do any additional setup after loading the view, typically from a nib. 142 | modalState = [[EMHint alloc] init]; 143 | [modalState setHintDelegate:self]; 144 | [modalState presentModalMessage:kFirstMessage where:_vc.navigationController.view]; 145 | } 146 | return self; 147 | } 148 | 149 | - (void)dealloc { 150 | 151 | [modalState release]; 152 | [super dealloc]; 153 | } 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /HintMakerExample/HintMakerExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | com.ericmcconkie.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /HintMakerExample/HintMakerExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'HintMakerExample' target in the 'HintMakerExample' 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 | -------------------------------------------------------------------------------- /HintMakerExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /HintMakerExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // HintMakerExample 4 | // 5 | // Created by Eric McConkie on 3/16/12. 6 | // Copyright (c) 2012. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "EMAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([EMAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /HintMakerExample/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mcconkiee/EMHint/1b65ddb91f8b7359a8d6ec857f06cd33d50c6785/HintMakerExample/sample.png -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Eric McConkie 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EMHint 2 | 3 | ## Overview 4 | 5 | **EMHint** is an iOS class group that easily adds multiple spotlight-like effects to a view highlighting or hinting at some things that may be important on the screen.The protocols of EMHintDelegate allow users to override many of the default actions and views. Tapping the black overlay fades it away. 6 | 7 | Great for quick "how to" or tutorials in your app. 8 | 9 | 10 | 11 | #### Installation 12 | 13 | 1. Drop in EMHint (.h/.m) & EMHintsView (.h/.m) 14 | 2. Pick a logical place to manage EMHintDelegate protocol implementation and conform to `` . 15 | 3. \#import "EMHint.h" 16 | 3. Call a new hint using the instance method `presentModalMessage:(NSString*)message where:(UIView*)presentationPlace` 17 | 3. You must implement `(CGRect)hintStateRectToHint:(id)hintState` **OR** `-(UIView*)hintStateViewToHint:(id)hintState` - without one, you will throw an exception. By doing so, EMHint can understand the radius of the spotlight to draw, and where-abouts. 18 | 19 | 20 | See the example app (`HintMakerExample`)in this build for more. 21 | #### Tips 22 | 1. It's possible to "daisy chain" hints. See the `HintHelper.m` class for a quick overview of using enums and protocol methods 23 | 2. Custom views can be added inplace of the default white text. Useful if you need to add a view or label not at center, or any custom graphics, etc 24 | 3. return CGRectMake(0,0,1,1) for an all black bg without spotlight….CGRectZero will fail. 25 | 4. Not ARC compliant….later. 26 | 27 | 28 | #### Todo's (limitations) 29 | 1. add rectangular spotlight (and other shapes) 30 | 2. different background colors/alpha/etc 31 | 3. support rotation (currently only label and background do so) 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | --------------------------------------------------------------------------------