├── .gitignore ├── .travis.yml ├── ARAutocompleteTextView.podspec ├── ARTextViewAutocompletion.png ├── ARTextViewAutocompletionExample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── HTTextFieldAutocompletionExample.xccheckout └── xcshareddata │ └── xcschemes │ └── ARTextViewAutocompletionExample.xcscheme ├── ARTextViewAutocompletionExample ├── ARAppDelegate.h ├── ARAppDelegate.m ├── ARAutocompleteManager.h ├── ARAutocompleteManager.m ├── ARSampleFieldsTableViewController.h ├── ARSampleFieldsTableViewController.m ├── ARTextViewAutocompletionExample-Info.plist ├── ARTextViewAutocompletionExample-Prefix.pch ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── MainStoryboard.storyboard └── main.m ├── ARTextViewAutocompletionExampleSwift.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── ARTextViewAutocompletionExampleSwift ├── ARTextViewAutocompletionExampleSwift-bridging-header.h ├── AppDelegate.swift ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist └── ViewController.swift ├── Classes ├── ARAutocompleteTextView.h ├── ARAutocompleteTextView.m ├── AREmailAutocompleteTextView.h ├── AREmailAutocompleteTextView.m ├── ARTwitterAutocompleteTextView.h └── ARTwitterAutocompleteTextView.m ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .svn 2 | .idea 3 | *.pyc 4 | .project 5 | .classpath 6 | *.mode1v3 7 | *.pbxuser 8 | *.DS_Store 9 | *~ 10 | *.swp 11 | xcuserdata 12 | xcshareddata 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | 3 | env: 4 | - XCODEBUILD_SETTINGS="-sdk iphonesimulator" -------------------------------------------------------------------------------- /ARAutocompleteTextView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'ARAutocompleteTextView' 3 | s.version = '0.1.0' 4 | s.summary = "Subclass of UITextView that automatically displays text suggestions in real-time." 5 | s.homepage = 'https://github.com/alexruperez/ARAutocompleteTextView' 6 | s.screenshots = 'https://raw.githubusercontent.com/alexruperez/ARAutocompleteTextView/master/ARTextViewAutocompletion.png' 7 | s.license = 'MIT' 8 | s.author = { "alexruperez" => "contact@alexruperez.com" } 9 | s.social_media_url = 'https://twitter.com/alexruperez' 10 | s.platform = :ios 11 | s.source = { :git => 'https://github.com/alexruperez/ARAutocompleteTextView.git', :tag => s.version.to_s } 12 | s.source_files = 'ARAutocompleteTextView', "Classes/*.{h,m}" 13 | s.requires_arc = true 14 | end -------------------------------------------------------------------------------- /ARTextViewAutocompletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexruperez/ARAutocompleteTextView/c6edbb63499f67c323dca72c1e4b5bfbd16873ea/ARTextViewAutocompletion.png -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8DF4A805168B7C610025E16D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DF4A804168B7C610025E16D /* UIKit.framework */; }; 11 | 8DF4A807168B7C610025E16D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DF4A806168B7C610025E16D /* Foundation.framework */; }; 12 | 8DF4A809168B7C610025E16D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DF4A808168B7C610025E16D /* CoreGraphics.framework */; }; 13 | D547717618069B440065533A /* ARAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D547717018069B440065533A /* ARAppDelegate.m */; }; 14 | D547717718069B440065533A /* ARAutocompleteManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D547717218069B440065533A /* ARAutocompleteManager.m */; }; 15 | D547717818069B440065533A /* ARSampleFieldsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D547717418069B440065533A /* ARSampleFieldsTableViewController.m */; }; 16 | D547717918069B440065533A /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D547717518069B440065533A /* MainStoryboard.storyboard */; }; 17 | D547718118069B7E0065533A /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D547717C18069B7E0065533A /* Default-568h@2x.png */; }; 18 | D547718218069B7E0065533A /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = D547717D18069B7E0065533A /* Default.png */; }; 19 | D547718318069B7E0065533A /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D547717E18069B7E0065533A /* Default@2x.png */; }; 20 | D547718418069B7E0065533A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D547717F18069B7E0065533A /* main.m */; }; 21 | D59957701BA2BD020089C1AB /* ARAutocompleteTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D599576B1BA2BD020089C1AB /* ARAutocompleteTextView.m */; }; 22 | D59957711BA2BD020089C1AB /* AREmailAutocompleteTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D599576D1BA2BD020089C1AB /* AREmailAutocompleteTextView.m */; }; 23 | D59957721BA2BD020089C1AB /* ARTwitterAutocompleteTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D599576F1BA2BD020089C1AB /* ARTwitterAutocompleteTextView.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 8DF4A800168B7C610025E16D /* ARTextViewAutocompletionExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ARTextViewAutocompletionExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | 8DF4A804168B7C610025E16D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 29 | 8DF4A806168B7C610025E16D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 30 | 8DF4A808168B7C610025E16D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 31 | D547716F18069B440065533A /* ARAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARAppDelegate.h; path = ARTextViewAutocompletionExample/ARAppDelegate.h; sourceTree = SOURCE_ROOT; }; 32 | D547717018069B440065533A /* ARAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARAppDelegate.m; path = ARTextViewAutocompletionExample/ARAppDelegate.m; sourceTree = SOURCE_ROOT; }; 33 | D547717118069B440065533A /* ARAutocompleteManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARAutocompleteManager.h; path = ARTextViewAutocompletionExample/ARAutocompleteManager.h; sourceTree = SOURCE_ROOT; }; 34 | D547717218069B440065533A /* ARAutocompleteManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARAutocompleteManager.m; path = ARTextViewAutocompletionExample/ARAutocompleteManager.m; sourceTree = SOURCE_ROOT; }; 35 | D547717318069B440065533A /* ARSampleFieldsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARSampleFieldsTableViewController.h; path = ARTextViewAutocompletionExample/ARSampleFieldsTableViewController.h; sourceTree = SOURCE_ROOT; }; 36 | D547717418069B440065533A /* ARSampleFieldsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARSampleFieldsTableViewController.m; path = ARTextViewAutocompletionExample/ARSampleFieldsTableViewController.m; sourceTree = SOURCE_ROOT; }; 37 | D547717518069B440065533A /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = MainStoryboard.storyboard; path = ARTextViewAutocompletionExample/MainStoryboard.storyboard; sourceTree = SOURCE_ROOT; }; 38 | D547717A18069B7E0065533A /* ARTextViewAutocompletionExample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "ARTextViewAutocompletionExample-Info.plist"; path = "ARTextViewAutocompletionExample/ARTextViewAutocompletionExample-Info.plist"; sourceTree = SOURCE_ROOT; }; 39 | D547717B18069B7E0065533A /* ARTextViewAutocompletionExample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ARTextViewAutocompletionExample-Prefix.pch"; path = "ARTextViewAutocompletionExample/ARTextViewAutocompletionExample-Prefix.pch"; sourceTree = SOURCE_ROOT; }; 40 | D547717C18069B7E0065533A /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "ARTextViewAutocompletionExample/Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; 41 | D547717D18069B7E0065533A /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = ARTextViewAutocompletionExample/Default.png; sourceTree = SOURCE_ROOT; }; 42 | D547717E18069B7E0065533A /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "ARTextViewAutocompletionExample/Default@2x.png"; sourceTree = SOURCE_ROOT; }; 43 | D547717F18069B7E0065533A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ARTextViewAutocompletionExample/main.m; sourceTree = SOURCE_ROOT; }; 44 | D599576A1BA2BD020089C1AB /* ARAutocompleteTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARAutocompleteTextView.h; path = Classes/ARAutocompleteTextView.h; sourceTree = SOURCE_ROOT; }; 45 | D599576B1BA2BD020089C1AB /* ARAutocompleteTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARAutocompleteTextView.m; path = Classes/ARAutocompleteTextView.m; sourceTree = SOURCE_ROOT; }; 46 | D599576C1BA2BD020089C1AB /* AREmailAutocompleteTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AREmailAutocompleteTextView.h; path = Classes/AREmailAutocompleteTextView.h; sourceTree = SOURCE_ROOT; }; 47 | D599576D1BA2BD020089C1AB /* AREmailAutocompleteTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AREmailAutocompleteTextView.m; path = Classes/AREmailAutocompleteTextView.m; sourceTree = SOURCE_ROOT; }; 48 | D599576E1BA2BD020089C1AB /* ARTwitterAutocompleteTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARTwitterAutocompleteTextView.h; path = Classes/ARTwitterAutocompleteTextView.h; sourceTree = SOURCE_ROOT; }; 49 | D599576F1BA2BD020089C1AB /* ARTwitterAutocompleteTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARTwitterAutocompleteTextView.m; path = Classes/ARTwitterAutocompleteTextView.m; sourceTree = SOURCE_ROOT; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 8DF4A7FD168B7C610025E16D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 8DF4A805168B7C610025E16D /* UIKit.framework in Frameworks */, 58 | 8DF4A807168B7C610025E16D /* Foundation.framework in Frameworks */, 59 | 8DF4A809168B7C610025E16D /* CoreGraphics.framework in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 8DF4A7F5168B7C610025E16D = { 67 | isa = PBXGroup; 68 | children = ( 69 | 8DF4A83A168B7CFC0025E16D /* Core */, 70 | 8DF4A80A168B7C610025E16D /* ARTextViewAutocompletionExample */, 71 | 8DF4A803168B7C610025E16D /* Frameworks */, 72 | 8DF4A801168B7C610025E16D /* Products */, 73 | ); 74 | sourceTree = ""; 75 | }; 76 | 8DF4A801168B7C610025E16D /* Products */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 8DF4A800168B7C610025E16D /* ARTextViewAutocompletionExample.app */, 80 | ); 81 | name = Products; 82 | sourceTree = ""; 83 | }; 84 | 8DF4A803168B7C610025E16D /* Frameworks */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 8DF4A804168B7C610025E16D /* UIKit.framework */, 88 | 8DF4A806168B7C610025E16D /* Foundation.framework */, 89 | 8DF4A808168B7C610025E16D /* CoreGraphics.framework */, 90 | ); 91 | name = Frameworks; 92 | sourceTree = ""; 93 | }; 94 | 8DF4A80A168B7C610025E16D /* ARTextViewAutocompletionExample */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | D547716F18069B440065533A /* ARAppDelegate.h */, 98 | D547717018069B440065533A /* ARAppDelegate.m */, 99 | D547717118069B440065533A /* ARAutocompleteManager.h */, 100 | D547717218069B440065533A /* ARAutocompleteManager.m */, 101 | D547717318069B440065533A /* ARSampleFieldsTableViewController.h */, 102 | D547717418069B440065533A /* ARSampleFieldsTableViewController.m */, 103 | D547717518069B440065533A /* MainStoryboard.storyboard */, 104 | 8DF4A80B168B7C610025E16D /* Supporting Files */, 105 | ); 106 | name = ARTextViewAutocompletionExample; 107 | path = HTTextFieldAutocompletionExample; 108 | sourceTree = ""; 109 | }; 110 | 8DF4A80B168B7C610025E16D /* Supporting Files */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | D547717A18069B7E0065533A /* ARTextViewAutocompletionExample-Info.plist */, 114 | D547717B18069B7E0065533A /* ARTextViewAutocompletionExample-Prefix.pch */, 115 | D547717C18069B7E0065533A /* Default-568h@2x.png */, 116 | D547717D18069B7E0065533A /* Default.png */, 117 | D547717E18069B7E0065533A /* Default@2x.png */, 118 | D547717F18069B7E0065533A /* main.m */, 119 | ); 120 | name = "Supporting Files"; 121 | sourceTree = ""; 122 | }; 123 | 8DF4A83A168B7CFC0025E16D /* Core */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | D599576A1BA2BD020089C1AB /* ARAutocompleteTextView.h */, 127 | D599576B1BA2BD020089C1AB /* ARAutocompleteTextView.m */, 128 | D599576C1BA2BD020089C1AB /* AREmailAutocompleteTextView.h */, 129 | D599576D1BA2BD020089C1AB /* AREmailAutocompleteTextView.m */, 130 | D599576E1BA2BD020089C1AB /* ARTwitterAutocompleteTextView.h */, 131 | D599576F1BA2BD020089C1AB /* ARTwitterAutocompleteTextView.m */, 132 | ); 133 | name = Core; 134 | path = HTTextFieldAutocompletionExample; 135 | sourceTree = ""; 136 | }; 137 | /* End PBXGroup section */ 138 | 139 | /* Begin PBXNativeTarget section */ 140 | 8DF4A7FF168B7C610025E16D /* ARTextViewAutocompletionExample */ = { 141 | isa = PBXNativeTarget; 142 | buildConfigurationList = 8DF4A827168B7C610025E16D /* Build configuration list for PBXNativeTarget "ARTextViewAutocompletionExample" */; 143 | buildPhases = ( 144 | 8DF4A7FC168B7C610025E16D /* Sources */, 145 | 8DF4A7FD168B7C610025E16D /* Frameworks */, 146 | 8DF4A7FE168B7C610025E16D /* Resources */, 147 | ); 148 | buildRules = ( 149 | ); 150 | dependencies = ( 151 | ); 152 | name = ARTextViewAutocompletionExample; 153 | productName = HTTextFieldAutocompletionExample; 154 | productReference = 8DF4A800168B7C610025E16D /* ARTextViewAutocompletionExample.app */; 155 | productType = "com.apple.product-type.application"; 156 | }; 157 | /* End PBXNativeTarget section */ 158 | 159 | /* Begin PBXProject section */ 160 | 8DF4A7F7168B7C610025E16D /* Project object */ = { 161 | isa = PBXProject; 162 | attributes = { 163 | CLASSPREFIX = AR; 164 | LastUpgradeCheck = 0450; 165 | ORGANIZATIONNAME = alexruperez; 166 | }; 167 | buildConfigurationList = 8DF4A7FA168B7C610025E16D /* Build configuration list for PBXProject "ARTextViewAutocompletionExample" */; 168 | compatibilityVersion = "Xcode 3.2"; 169 | developmentRegion = English; 170 | hasScannedForEncodings = 0; 171 | knownRegions = ( 172 | en, 173 | ); 174 | mainGroup = 8DF4A7F5168B7C610025E16D; 175 | productRefGroup = 8DF4A801168B7C610025E16D /* Products */; 176 | projectDirPath = ""; 177 | projectRoot = ""; 178 | targets = ( 179 | 8DF4A7FF168B7C610025E16D /* ARTextViewAutocompletionExample */, 180 | ); 181 | }; 182 | /* End PBXProject section */ 183 | 184 | /* Begin PBXResourcesBuildPhase section */ 185 | 8DF4A7FE168B7C610025E16D /* Resources */ = { 186 | isa = PBXResourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | D547717918069B440065533A /* MainStoryboard.storyboard in Resources */, 190 | D547718118069B7E0065533A /* Default-568h@2x.png in Resources */, 191 | D547718218069B7E0065533A /* Default.png in Resources */, 192 | D547718318069B7E0065533A /* Default@2x.png in Resources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXResourcesBuildPhase section */ 197 | 198 | /* Begin PBXSourcesBuildPhase section */ 199 | 8DF4A7FC168B7C610025E16D /* Sources */ = { 200 | isa = PBXSourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | D59957701BA2BD020089C1AB /* ARAutocompleteTextView.m in Sources */, 204 | D547717618069B440065533A /* ARAppDelegate.m in Sources */, 205 | D59957711BA2BD020089C1AB /* AREmailAutocompleteTextView.m in Sources */, 206 | D547717718069B440065533A /* ARAutocompleteManager.m in Sources */, 207 | D547717818069B440065533A /* ARSampleFieldsTableViewController.m in Sources */, 208 | D547718418069B7E0065533A /* main.m in Sources */, 209 | D59957721BA2BD020089C1AB /* ARTwitterAutocompleteTextView.m in Sources */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | /* End PBXSourcesBuildPhase section */ 214 | 215 | /* Begin XCBuildConfiguration section */ 216 | 8DF4A825168B7C610025E16D /* Debug */ = { 217 | isa = XCBuildConfiguration; 218 | buildSettings = { 219 | ALWAYS_SEARCH_USER_PATHS = NO; 220 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 221 | CLANG_CXX_LIBRARY = "libc++"; 222 | CLANG_ENABLE_OBJC_ARC = YES; 223 | CLANG_WARN_EMPTY_BODY = YES; 224 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 225 | COPY_PHASE_STRIP = NO; 226 | GCC_C_LANGUAGE_STANDARD = gnu99; 227 | GCC_DYNAMIC_NO_PIC = NO; 228 | GCC_OPTIMIZATION_LEVEL = 0; 229 | GCC_PREPROCESSOR_DEFINITIONS = ( 230 | "DEBUG=1", 231 | "$(inherited)", 232 | ); 233 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 234 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 235 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 236 | GCC_WARN_UNUSED_VARIABLE = YES; 237 | INFOPLIST_FILE = "ARTextViewAutocompletionExample/ARTextViewAutocompletionExample-Info.plist"; 238 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 239 | ONLY_ACTIVE_ARCH = YES; 240 | SDKROOT = iphoneos; 241 | TARGETED_DEVICE_FAMILY = "1,2"; 242 | }; 243 | name = Debug; 244 | }; 245 | 8DF4A826168B7C610025E16D /* Release */ = { 246 | isa = XCBuildConfiguration; 247 | buildSettings = { 248 | ALWAYS_SEARCH_USER_PATHS = NO; 249 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 250 | CLANG_CXX_LIBRARY = "libc++"; 251 | CLANG_ENABLE_OBJC_ARC = YES; 252 | CLANG_WARN_EMPTY_BODY = YES; 253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 254 | COPY_PHASE_STRIP = YES; 255 | GCC_C_LANGUAGE_STANDARD = gnu99; 256 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 257 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | INFOPLIST_FILE = "ARTextViewAutocompletionExample/ARTextViewAutocompletionExample-Info.plist"; 260 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 261 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 262 | SDKROOT = iphoneos; 263 | TARGETED_DEVICE_FAMILY = "1,2"; 264 | VALIDATE_PRODUCT = YES; 265 | }; 266 | name = Release; 267 | }; 268 | 8DF4A828168B7C610025E16D /* Debug */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | CODE_SIGN_IDENTITY = "iPhone Developer"; 272 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 273 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 274 | PRODUCT_NAME = "$(TARGET_NAME)"; 275 | TARGETED_DEVICE_FAMILY = "1,2"; 276 | WRAPPER_EXTENSION = app; 277 | }; 278 | name = Debug; 279 | }; 280 | 8DF4A829168B7C610025E16D /* Release */ = { 281 | isa = XCBuildConfiguration; 282 | buildSettings = { 283 | CODE_SIGN_IDENTITY = "iPhone Developer"; 284 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 285 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 286 | PRODUCT_NAME = "$(TARGET_NAME)"; 287 | TARGETED_DEVICE_FAMILY = "1,2"; 288 | WRAPPER_EXTENSION = app; 289 | }; 290 | name = Release; 291 | }; 292 | /* End XCBuildConfiguration section */ 293 | 294 | /* Begin XCConfigurationList section */ 295 | 8DF4A7FA168B7C610025E16D /* Build configuration list for PBXProject "ARTextViewAutocompletionExample" */ = { 296 | isa = XCConfigurationList; 297 | buildConfigurations = ( 298 | 8DF4A825168B7C610025E16D /* Debug */, 299 | 8DF4A826168B7C610025E16D /* Release */, 300 | ); 301 | defaultConfigurationIsVisible = 0; 302 | defaultConfigurationName = Release; 303 | }; 304 | 8DF4A827168B7C610025E16D /* Build configuration list for PBXNativeTarget "ARTextViewAutocompletionExample" */ = { 305 | isa = XCConfigurationList; 306 | buildConfigurations = ( 307 | 8DF4A828168B7C610025E16D /* Debug */, 308 | 8DF4A829168B7C610025E16D /* Release */, 309 | ); 310 | defaultConfigurationIsVisible = 0; 311 | defaultConfigurationName = Release; 312 | }; 313 | /* End XCConfigurationList section */ 314 | }; 315 | rootObject = 8DF4A7F7168B7C610025E16D /* Project object */; 316 | } 317 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample.xcodeproj/project.xcworkspace/xcshareddata/HTTextFieldAutocompletionExample.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 29E42085-1ED1-4EF5-88FA-9B229318924A 9 | IDESourceControlProjectName 10 | HTTextFieldAutocompletionExample 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 91ABCBDB-BF42-4AA8-8080-7C8C47DD12B3 14 | https://github.com/hoteltonight/HTAutocompleteTextField.git 15 | 16 | IDESourceControlProjectPath 17 | HTTextFieldAutocompletionExample.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 91ABCBDB-BF42-4AA8-8080-7C8C47DD12B3 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/hoteltonight/HTAutocompleteTextField.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 91ABCBDB-BF42-4AA8-8080-7C8C47DD12B3 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 91ABCBDB-BF42-4AA8-8080-7C8C47DD12B3 36 | IDESourceControlWCCName 37 | HTAutocompleteTextField 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample.xcodeproj/xcshareddata/xcschemes/ARTextViewAutocompletionExample.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 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/ARAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARAppDelegate.h 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 12/26/12. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ARViewController; 12 | 13 | @interface ARAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) ARViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/ARAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARAppDelegate.m 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 12/26/12. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import "ARAppDelegate.h" 10 | 11 | @implementation ARAppDelegate 12 | 13 | //- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | //{ 15 | // return YES; 16 | //} 17 | 18 | - (void)applicationWillResignActive:(UIApplication *)application 19 | { 20 | // 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. 21 | // 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. 22 | } 23 | 24 | - (void)applicationDidEnterBackground:(UIApplication *)application 25 | { 26 | // 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. 27 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 28 | } 29 | 30 | - (void)applicationWillEnterForeground:(UIApplication *)application 31 | { 32 | // 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. 33 | } 34 | 35 | - (void)applicationDidBecomeActive:(UIApplication *)application 36 | { 37 | // 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. 38 | } 39 | 40 | - (void)applicationWillTerminate:(UIApplication *)application 41 | { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/ARAutocompleteManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARAutocompleteManager.h 3 | // alexruperez 4 | // 5 | // Created by Alejandro Rupérez on 12/6/12. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ARAutocompleteTextView.h" 11 | 12 | typedef enum { 13 | ARAutocompleteTypeEmail, // Default 14 | ARAutocompleteTypeNames, 15 | } ARAutocompleteType; 16 | 17 | @interface ARAutocompleteManager : NSObject 18 | 19 | + (ARAutocompleteManager *)sharedManager; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/ARAutocompleteManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARAutocompleteManager.m 3 | // alexruperez 4 | // 5 | // Created by Alejandro Rupérez on 12/6/12. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import "ARAutocompleteManager.h" 10 | 11 | static ARAutocompleteManager *sharedManager; 12 | 13 | @implementation ARAutocompleteManager 14 | 15 | + (ARAutocompleteManager *)sharedManager 16 | { 17 | static dispatch_once_t done; 18 | dispatch_once(&done, ^{ sharedManager = [[ARAutocompleteManager alloc] init]; }); 19 | return sharedManager; 20 | } 21 | 22 | #pragma mark - ARAutocompleteTextViewDelegate 23 | 24 | - (NSString *)textView:(ARAutocompleteTextView *)textView 25 | completionForPrefix:(NSString *)prefix 26 | ignoreCase:(BOOL)ignoreCase 27 | { 28 | if (textView.autocompleteType == ARAutocompleteTypeEmail) 29 | { 30 | static dispatch_once_t onceToken; 31 | static NSArray *autocompleteArray; 32 | dispatch_once(&onceToken, ^ 33 | { 34 | autocompleteArray = @[ @"gmail.com", 35 | @"yahoo.com", 36 | @"hotmail.com", 37 | @"aol.com", 38 | @"comcast.net", 39 | @"me.com", 40 | @"msn.com", 41 | @"live.com", 42 | @"sbcglobal.net", 43 | @"ymail.com", 44 | @"att.net", 45 | @"mac.com", 46 | @"cox.net", 47 | @"verizon.net", 48 | @"hotmail.co.uk", 49 | @"bellsouth.net", 50 | @"rocketmail.com", 51 | @"aim.com", 52 | @"yahoo.co.uk", 53 | @"earthlink.net", 54 | @"charter.net", 55 | @"optonline.net", 56 | @"shaw.ca", 57 | @"yahoo.ca", 58 | @"googlemail.com", 59 | @"mail.com", 60 | @"qq.com", 61 | @"btinternet.com", 62 | @"mail.ru", 63 | @"live.co.uk", 64 | @"naver.com", 65 | @"rogers.com", 66 | @"juno.com", 67 | @"yahoo.com.tw", 68 | @"live.ca", 69 | @"walla.com", 70 | @"163.com", 71 | @"roadrunner.com", 72 | @"telus.net", 73 | @"embarqmail.com", 74 | @"hotmail.fr", 75 | @"pacbell.net", 76 | @"sky.com", 77 | @"sympatico.ca", 78 | @"cfl.rr.com", 79 | @"tampabay.rr.com", 80 | @"q.com", 81 | @"yahoo.co.in", 82 | @"yahoo.fr", 83 | @"hotmail.ca", 84 | @"windstream.net", 85 | @"hotmail.it", 86 | @"web.de", 87 | @"asu.edu", 88 | @"gmx.de", 89 | @"gmx.com", 90 | @"insightbb.com", 91 | @"netscape.net", 92 | @"icloud.com", 93 | @"frontier.com", 94 | @"126.com", 95 | @"hanmail.net", 96 | @"suddenlink.net", 97 | @"netzero.net", 98 | @"mindspring.com", 99 | @"ail.com", 100 | @"windowslive.com", 101 | @"netzero.com", 102 | @"yahoo.com.hk", 103 | @"yandex.ru", 104 | @"mchsi.com", 105 | @"cableone.net", 106 | @"yahoo.com.cn", 107 | @"yahoo.es", 108 | @"yahoo.com.br", 109 | @"cornell.edu", 110 | @"ucla.edu", 111 | @"us.army.mil", 112 | @"excite.com", 113 | @"ntlworld.com", 114 | @"usc.edu", 115 | @"nate.com", 116 | @"outlook.com", 117 | @"nc.rr.com", 118 | @"prodigy.net", 119 | @"wi.rr.com", 120 | @"videotron.ca", 121 | @"yahoo.it", 122 | @"yahoo.com.au", 123 | @"umich.edu", 124 | @"ameritech.net", 125 | @"libero.it", 126 | @"yahoo.de", 127 | @"rochester.rr.com", 128 | @"cs.com", 129 | @"frontiernet.net", 130 | @"swbell.net", 131 | @"msu.edu", 132 | @"ptd.net", 133 | @"proxymail.facebook.com", 134 | @"hotmail.es", 135 | @"austin.rr.com", 136 | @"nyu.edu", 137 | @"sina.com", 138 | @"centurytel.net", 139 | @"usa.net", 140 | @"nycap.rr.com", 141 | @"uci.edu", 142 | @"hotmail.de", 143 | @"yahoo.com.sg", 144 | @"email.arizona.edu", 145 | @"yahoo.com.mx", 146 | @"ufl.edu", 147 | @"bigpond.com", 148 | @"unlv.nevada.edu", 149 | @"yahoo.cn", 150 | @"ca.rr.com", 151 | @"google.com", 152 | @"yahoo.co.id", 153 | @"inbox.com", 154 | @"fuse.net", 155 | @"hawaii.rr.com", 156 | @"talktalk.net", 157 | @"gmx.net", 158 | @"walla.co.il", 159 | @"ucdavis.edu", 160 | @"carolina.rr.com", 161 | @"comcast.com", 162 | @"live.fr", 163 | @"blueyonder.co.uk", 164 | @"live.cn", 165 | @"cogeco.ca", 166 | @"abv.bg", 167 | @"tds.net", 168 | @"centurylink.net", 169 | @"yahoo.com.vn", 170 | @"uol.com.br", 171 | @"osu.edu", 172 | @"san.rr.com", 173 | @"rcn.com", 174 | @"umn.edu", 175 | @"live.nl", 176 | @"live.com.au", 177 | @"tx.rr.com", 178 | @"eircom.net", 179 | @"sasktel.net", 180 | @"post.harvard.edu", 181 | @"snet.net", 182 | @"wowway.com", 183 | @"live.it", 184 | @"att.com", 185 | @"vt.edu", 186 | @"rambler.ru", 187 | @"temple.edu", 188 | @"cinci.rr.com", 189 | @"alexruperez.com", 190 | @"feverup.com"]; 191 | }); 192 | 193 | // Check that text field contains an @ 194 | NSRange atSignRange = [prefix rangeOfString:@"@"]; 195 | if (atSignRange.location == NSNotFound) 196 | { 197 | return @""; 198 | } 199 | 200 | // Stop autocomplete if user types dot after domain 201 | NSString *domainAndTLD = [prefix substringFromIndex:atSignRange.location]; 202 | NSRange rangeOfDot = [domainAndTLD rangeOfString:@"."]; 203 | if (rangeOfDot.location != NSNotFound) 204 | { 205 | return @""; 206 | } 207 | 208 | // Check that there aren't two @-signs 209 | NSArray *textComponents = [prefix componentsSeparatedByString:@"@"]; 210 | if ([textComponents count] > 2) 211 | { 212 | return @""; 213 | } 214 | 215 | if ([textComponents count] > 1) 216 | { 217 | // If no domain is entered, use the first domain in the list 218 | if ([(NSString *)textComponents[1] length] == 0) 219 | { 220 | return [autocompleteArray objectAtIndex:0]; 221 | } 222 | 223 | NSString *textAfterAtSign = textComponents[1]; 224 | 225 | NSString *stringToLookFor; 226 | if (ignoreCase) 227 | { 228 | stringToLookFor = [textAfterAtSign lowercaseString]; 229 | } 230 | else 231 | { 232 | stringToLookFor = textAfterAtSign; 233 | } 234 | 235 | for (NSString *stringFromReference in autocompleteArray) 236 | { 237 | NSString *stringToCompare; 238 | if (ignoreCase) 239 | { 240 | stringToCompare = [stringFromReference lowercaseString]; 241 | } 242 | else 243 | { 244 | stringToCompare = stringFromReference; 245 | } 246 | 247 | if ([stringToCompare hasPrefix:stringToLookFor]) 248 | { 249 | return [stringFromReference stringByReplacingCharactersInRange:[stringToCompare rangeOfString:stringToLookFor] withString:@""]; 250 | } 251 | 252 | } 253 | } 254 | } 255 | else if (textView.autocompleteType == ARAutocompleteTypeNames) 256 | { 257 | static dispatch_once_t colorOnceToken; 258 | static NSArray *colorAutocompleteArray; 259 | dispatch_once(&colorOnceToken, ^ 260 | { 261 | colorAutocompleteArray = @[ @"Alex", 262 | @"Alfred", 263 | @"Beth", 264 | @"Carlos", 265 | @"Cris", 266 | @"Daniel", 267 | @"Ethan", 268 | @"Fred", 269 | @"George", 270 | @"Helen", 271 | @"Inis", 272 | @"Jennifer", 273 | @"Kylie", 274 | @"Liam", 275 | @"Melissa", 276 | @"Noah", 277 | @"Omar", 278 | @"Penelope", 279 | @"Quan", 280 | @"Rachel", 281 | @"Seth", 282 | @"Timothy", 283 | @"Ulga", 284 | @"Vanessa", 285 | @"William", 286 | @"Xao", 287 | @"Yilton", 288 | @"Zander"]; 289 | }); 290 | 291 | NSString *stringToLookFor; 292 | NSArray *componentsString = [prefix componentsSeparatedByString:@","]; 293 | NSString *prefixLastComponent = [componentsString.lastObject stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 294 | if (ignoreCase) 295 | { 296 | stringToLookFor = [prefixLastComponent lowercaseString]; 297 | } 298 | else 299 | { 300 | stringToLookFor = prefixLastComponent; 301 | } 302 | 303 | for (NSString *stringFromReference in colorAutocompleteArray) 304 | { 305 | NSString *stringToCompare; 306 | if (ignoreCase) 307 | { 308 | stringToCompare = [stringFromReference lowercaseString]; 309 | } 310 | else 311 | { 312 | stringToCompare = stringFromReference; 313 | } 314 | 315 | if ([stringToCompare hasPrefix:stringToLookFor]) 316 | { 317 | return [stringFromReference stringByReplacingCharactersInRange:[stringToCompare rangeOfString:stringToLookFor] withString:@""]; 318 | } 319 | 320 | } 321 | } 322 | 323 | return @""; 324 | } 325 | 326 | @end 327 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/ARSampleFieldsTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARSampleFieldsTableViewController.h 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 12/26/12. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ARAutocompleteTextView.h" 11 | #import "AREmailAutocompleteTextView.h" 12 | #import "ARTwitterAutocompleteTextView.h" 13 | 14 | @interface ARSampleFieldsTableViewController : UITableViewController 15 | 16 | @property (unsafe_unretained, nonatomic) IBOutlet AREmailAutocompleteTextView *emailTextView; 17 | @property (unsafe_unretained, nonatomic) IBOutlet ARTwitterAutocompleteTextView *allTextView; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/ARSampleFieldsTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARSampleFieldsTableViewController.m 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 12/26/12. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import "ARSampleFieldsTableViewController.h" 10 | #import "ARAutocompleteManager.h" 11 | 12 | @interface ARSampleFieldsTableViewController () 13 | 14 | @end 15 | 16 | @implementation ARSampleFieldsTableViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | 22 | // Set a default data source for all ARAutocompleteTextView instances. Otherwise, you can specify the data source on individual text fields via the autocompleteDataSource property or use my default AREmailAutocompleteTextView and ARTwitterAutocompleteTextView like in this sample 23 | [ARAutocompleteTextView setDefaultAutocompleteDataSource:[ARAutocompleteManager sharedManager]]; 24 | 25 | // Dismiss the keyboard when the user taps outside of a text field 26 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; 27 | [self.view addGestureRecognizer:singleTap]; 28 | } 29 | 30 | - (void)handleSingleTap:(UITapGestureRecognizer *)sender 31 | { 32 | [self.emailTextView resignFirstResponder]; 33 | [self.allTextView resignFirstResponder]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/ARTextViewAutocompletionExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.alexruperez.${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 | UIMainStoryboardFile~ipad 28 | MainStoryboard 29 | UIMainStoryboardFile~iphone 30 | MainStoryboard 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | UIInterfaceOrientationPortraitUpsideDown 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/ARTextViewAutocompletionExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ARTextViewAutocompletionExample' target in the 'ARTextViewAutocompletionExample' 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 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexruperez/ARAutocompleteTextView/c6edbb63499f67c323dca72c1e4b5bfbd16873ea/ARTextViewAutocompletionExample/Default-568h@2x.png -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexruperez/ARAutocompleteTextView/c6edbb63499f67c323dca72c1e4b5bfbd16873ea/ARTextViewAutocompletionExample/Default.png -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexruperez/ARAutocompleteTextView/c6edbb63499f67c323dca72c1e4b5bfbd16873ea/ARTextViewAutocompletionExample/Default@2x.png -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/MainStoryboard.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 50 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 87 | 94 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 12/26/12. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ARAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([ARAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C2B3C3FC1BA2671B002344AE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2B3C3FB1BA2671B002344AE /* AppDelegate.swift */; }; 11 | C2B3C3FE1BA2671B002344AE /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2B3C3FD1BA2671B002344AE /* ViewController.swift */; }; 12 | C2B3C4011BA2671B002344AE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C2B3C3FF1BA2671B002344AE /* Main.storyboard */; }; 13 | C2B3C4031BA2671B002344AE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C2B3C4021BA2671B002344AE /* Images.xcassets */; }; 14 | C2B3C4061BA2671B002344AE /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = C2B3C4041BA2671B002344AE /* LaunchScreen.xib */; }; 15 | D59957791BA2BD450089C1AB /* ARAutocompleteTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D59957741BA2BD450089C1AB /* ARAutocompleteTextView.m */; }; 16 | D599577A1BA2BD450089C1AB /* AREmailAutocompleteTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D59957761BA2BD450089C1AB /* AREmailAutocompleteTextView.m */; }; 17 | D599577B1BA2BD450089C1AB /* ARTwitterAutocompleteTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = D59957781BA2BD450089C1AB /* ARTwitterAutocompleteTextView.m */; }; 18 | D599577F1BA2BD890089C1AB /* ARAutocompleteManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D599577E1BA2BD890089C1AB /* ARAutocompleteManager.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | C2B3C3F61BA2671B002344AE /* ARTextViewAutocompletionExampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ARTextViewAutocompletionExampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | C2B3C3FA1BA2671B002344AE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 24 | C2B3C3FB1BA2671B002344AE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 25 | C2B3C3FD1BA2671B002344AE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 26 | C2B3C4001BA2671B002344AE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 27 | C2B3C4021BA2671B002344AE /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 28 | C2B3C4051BA2671B002344AE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 29 | C2B3C4101BA2671B002344AE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 30 | C2B3C4111BA2671B002344AE /* ARTextViewAutocompletionExampleSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARTextViewAutocompletionExampleSwiftTests.swift; sourceTree = ""; }; 31 | D59957731BA2BD450089C1AB /* ARAutocompleteTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARAutocompleteTextView.h; sourceTree = ""; }; 32 | D59957741BA2BD450089C1AB /* ARAutocompleteTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARAutocompleteTextView.m; sourceTree = ""; }; 33 | D59957751BA2BD450089C1AB /* AREmailAutocompleteTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AREmailAutocompleteTextView.h; sourceTree = ""; }; 34 | D59957761BA2BD450089C1AB /* AREmailAutocompleteTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AREmailAutocompleteTextView.m; sourceTree = ""; }; 35 | D59957771BA2BD450089C1AB /* ARTwitterAutocompleteTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTwitterAutocompleteTextView.h; sourceTree = ""; }; 36 | D59957781BA2BD450089C1AB /* ARTwitterAutocompleteTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTwitterAutocompleteTextView.m; sourceTree = ""; }; 37 | D599577C1BA2BD4F0089C1AB /* ARTextViewAutocompletionExampleSwift-bridging-header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ARTextViewAutocompletionExampleSwift-bridging-header.h"; sourceTree = ""; }; 38 | D599577D1BA2BD890089C1AB /* ARAutocompleteManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARAutocompleteManager.h; path = ARTextViewAutocompletionExample/ARAutocompleteManager.h; sourceTree = SOURCE_ROOT; }; 39 | D599577E1BA2BD890089C1AB /* ARAutocompleteManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ARAutocompleteManager.m; path = ARTextViewAutocompletionExample/ARAutocompleteManager.m; sourceTree = SOURCE_ROOT; }; 40 | /* End PBXFileReference section */ 41 | 42 | /* Begin PBXFrameworksBuildPhase section */ 43 | C2B3C3F31BA2671B002344AE /* Frameworks */ = { 44 | isa = PBXFrameworksBuildPhase; 45 | buildActionMask = 2147483647; 46 | files = ( 47 | ); 48 | runOnlyForDeploymentPostprocessing = 0; 49 | }; 50 | /* End PBXFrameworksBuildPhase section */ 51 | 52 | /* Begin PBXGroup section */ 53 | C2B3C3ED1BA2671B002344AE = { 54 | isa = PBXGroup; 55 | children = ( 56 | C2B3C41B1BA26730002344AE /* Classes */, 57 | C2B3C3F81BA2671B002344AE /* ARTextViewAutocompletionExampleSwift */, 58 | C2B3C40E1BA2671B002344AE /* ARTextViewAutocompletionExampleSwiftTests */, 59 | C2B3C3F71BA2671B002344AE /* Products */, 60 | ); 61 | sourceTree = ""; 62 | }; 63 | C2B3C3F71BA2671B002344AE /* Products */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | C2B3C3F61BA2671B002344AE /* ARTextViewAutocompletionExampleSwift.app */, 67 | ); 68 | name = Products; 69 | sourceTree = ""; 70 | }; 71 | C2B3C3F81BA2671B002344AE /* ARTextViewAutocompletionExampleSwift */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | D599577D1BA2BD890089C1AB /* ARAutocompleteManager.h */, 75 | D599577E1BA2BD890089C1AB /* ARAutocompleteManager.m */, 76 | D599577C1BA2BD4F0089C1AB /* ARTextViewAutocompletionExampleSwift-bridging-header.h */, 77 | C2B3C3FB1BA2671B002344AE /* AppDelegate.swift */, 78 | C2B3C3FD1BA2671B002344AE /* ViewController.swift */, 79 | C2B3C3FF1BA2671B002344AE /* Main.storyboard */, 80 | C2B3C4021BA2671B002344AE /* Images.xcassets */, 81 | C2B3C4041BA2671B002344AE /* LaunchScreen.xib */, 82 | C2B3C3F91BA2671B002344AE /* Supporting Files */, 83 | ); 84 | path = ARTextViewAutocompletionExampleSwift; 85 | sourceTree = ""; 86 | }; 87 | C2B3C3F91BA2671B002344AE /* Supporting Files */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | C2B3C3FA1BA2671B002344AE /* Info.plist */, 91 | ); 92 | name = "Supporting Files"; 93 | sourceTree = ""; 94 | }; 95 | C2B3C40E1BA2671B002344AE /* ARTextViewAutocompletionExampleSwiftTests */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | C2B3C4111BA2671B002344AE /* ARTextViewAutocompletionExampleSwiftTests.swift */, 99 | C2B3C40F1BA2671B002344AE /* Supporting Files */, 100 | ); 101 | path = ARTextViewAutocompletionExampleSwiftTests; 102 | sourceTree = ""; 103 | }; 104 | C2B3C40F1BA2671B002344AE /* Supporting Files */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | C2B3C4101BA2671B002344AE /* Info.plist */, 108 | ); 109 | name = "Supporting Files"; 110 | sourceTree = ""; 111 | }; 112 | C2B3C41B1BA26730002344AE /* Classes */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | D59957731BA2BD450089C1AB /* ARAutocompleteTextView.h */, 116 | D59957741BA2BD450089C1AB /* ARAutocompleteTextView.m */, 117 | D59957751BA2BD450089C1AB /* AREmailAutocompleteTextView.h */, 118 | D59957761BA2BD450089C1AB /* AREmailAutocompleteTextView.m */, 119 | D59957771BA2BD450089C1AB /* ARTwitterAutocompleteTextView.h */, 120 | D59957781BA2BD450089C1AB /* ARTwitterAutocompleteTextView.m */, 121 | ); 122 | path = Classes; 123 | sourceTree = ""; 124 | }; 125 | /* End PBXGroup section */ 126 | 127 | /* Begin PBXNativeTarget section */ 128 | C2B3C3F51BA2671B002344AE /* ARTextViewAutocompletionExampleSwift */ = { 129 | isa = PBXNativeTarget; 130 | buildConfigurationList = C2B3C4151BA2671B002344AE /* Build configuration list for PBXNativeTarget "ARTextViewAutocompletionExampleSwift" */; 131 | buildPhases = ( 132 | C2B3C3F21BA2671B002344AE /* Sources */, 133 | C2B3C3F31BA2671B002344AE /* Frameworks */, 134 | C2B3C3F41BA2671B002344AE /* Resources */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = ARTextViewAutocompletionExampleSwift; 141 | productName = ARTextViewAutocompletionExampleSwift; 142 | productReference = C2B3C3F61BA2671B002344AE /* ARTextViewAutocompletionExampleSwift.app */; 143 | productType = "com.apple.product-type.application"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | C2B3C3EE1BA2671B002344AE /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastSwiftUpdateCheck = 0700; 152 | LastUpgradeCheck = 0640; 153 | ORGANIZATIONNAME = "Lucas Farah"; 154 | TargetAttributes = { 155 | C2B3C3F51BA2671B002344AE = { 156 | CreatedOnToolsVersion = 6.4; 157 | }; 158 | }; 159 | }; 160 | buildConfigurationList = C2B3C3F11BA2671B002344AE /* Build configuration list for PBXProject "ARTextViewAutocompletionExampleSwift" */; 161 | compatibilityVersion = "Xcode 3.2"; 162 | developmentRegion = English; 163 | hasScannedForEncodings = 0; 164 | knownRegions = ( 165 | en, 166 | Base, 167 | ); 168 | mainGroup = C2B3C3ED1BA2671B002344AE; 169 | productRefGroup = C2B3C3F71BA2671B002344AE /* Products */; 170 | projectDirPath = ""; 171 | projectRoot = ""; 172 | targets = ( 173 | C2B3C3F51BA2671B002344AE /* ARTextViewAutocompletionExampleSwift */, 174 | ); 175 | }; 176 | /* End PBXProject section */ 177 | 178 | /* Begin PBXResourcesBuildPhase section */ 179 | C2B3C3F41BA2671B002344AE /* Resources */ = { 180 | isa = PBXResourcesBuildPhase; 181 | buildActionMask = 2147483647; 182 | files = ( 183 | C2B3C4011BA2671B002344AE /* Main.storyboard in Resources */, 184 | C2B3C4061BA2671B002344AE /* LaunchScreen.xib in Resources */, 185 | C2B3C4031BA2671B002344AE /* Images.xcassets in Resources */, 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXResourcesBuildPhase section */ 190 | 191 | /* Begin PBXSourcesBuildPhase section */ 192 | C2B3C3F21BA2671B002344AE /* Sources */ = { 193 | isa = PBXSourcesBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | C2B3C3FE1BA2671B002344AE /* ViewController.swift in Sources */, 197 | D599577A1BA2BD450089C1AB /* AREmailAutocompleteTextView.m in Sources */, 198 | D599577F1BA2BD890089C1AB /* ARAutocompleteManager.m in Sources */, 199 | D59957791BA2BD450089C1AB /* ARAutocompleteTextView.m in Sources */, 200 | D599577B1BA2BD450089C1AB /* ARTwitterAutocompleteTextView.m in Sources */, 201 | C2B3C3FC1BA2671B002344AE /* AppDelegate.swift in Sources */, 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | }; 205 | /* End PBXSourcesBuildPhase section */ 206 | 207 | /* Begin PBXVariantGroup section */ 208 | C2B3C3FF1BA2671B002344AE /* Main.storyboard */ = { 209 | isa = PBXVariantGroup; 210 | children = ( 211 | C2B3C4001BA2671B002344AE /* Base */, 212 | ); 213 | name = Main.storyboard; 214 | sourceTree = ""; 215 | }; 216 | C2B3C4041BA2671B002344AE /* LaunchScreen.xib */ = { 217 | isa = PBXVariantGroup; 218 | children = ( 219 | C2B3C4051BA2671B002344AE /* Base */, 220 | ); 221 | name = LaunchScreen.xib; 222 | sourceTree = ""; 223 | }; 224 | /* End PBXVariantGroup section */ 225 | 226 | /* Begin XCBuildConfiguration section */ 227 | C2B3C4131BA2671B002344AE /* Debug */ = { 228 | isa = XCBuildConfiguration; 229 | buildSettings = { 230 | ALWAYS_SEARCH_USER_PATHS = NO; 231 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 232 | CLANG_CXX_LIBRARY = "libc++"; 233 | CLANG_ENABLE_MODULES = YES; 234 | CLANG_ENABLE_OBJC_ARC = YES; 235 | CLANG_WARN_BOOL_CONVERSION = YES; 236 | CLANG_WARN_CONSTANT_CONVERSION = YES; 237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 238 | CLANG_WARN_EMPTY_BODY = YES; 239 | CLANG_WARN_ENUM_CONVERSION = YES; 240 | CLANG_WARN_INT_CONVERSION = YES; 241 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 242 | CLANG_WARN_UNREACHABLE_CODE = YES; 243 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 244 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 245 | COPY_PHASE_STRIP = NO; 246 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 247 | ENABLE_STRICT_OBJC_MSGSEND = YES; 248 | GCC_C_LANGUAGE_STANDARD = gnu99; 249 | GCC_DYNAMIC_NO_PIC = NO; 250 | GCC_NO_COMMON_BLOCKS = YES; 251 | GCC_OPTIMIZATION_LEVEL = 0; 252 | GCC_PREPROCESSOR_DEFINITIONS = ( 253 | "DEBUG=1", 254 | "$(inherited)", 255 | ); 256 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 257 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 258 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 259 | GCC_WARN_UNDECLARED_SELECTOR = YES; 260 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 261 | GCC_WARN_UNUSED_FUNCTION = YES; 262 | GCC_WARN_UNUSED_VARIABLE = YES; 263 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 264 | MTL_ENABLE_DEBUG_INFO = YES; 265 | ONLY_ACTIVE_ARCH = YES; 266 | SDKROOT = iphoneos; 267 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 268 | }; 269 | name = Debug; 270 | }; 271 | C2B3C4141BA2671B002344AE /* Release */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | ALWAYS_SEARCH_USER_PATHS = NO; 275 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 276 | CLANG_CXX_LIBRARY = "libc++"; 277 | CLANG_ENABLE_MODULES = YES; 278 | CLANG_ENABLE_OBJC_ARC = YES; 279 | CLANG_WARN_BOOL_CONVERSION = YES; 280 | CLANG_WARN_CONSTANT_CONVERSION = YES; 281 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 282 | CLANG_WARN_EMPTY_BODY = YES; 283 | CLANG_WARN_ENUM_CONVERSION = YES; 284 | CLANG_WARN_INT_CONVERSION = YES; 285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 286 | CLANG_WARN_UNREACHABLE_CODE = YES; 287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 288 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 289 | COPY_PHASE_STRIP = NO; 290 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 291 | ENABLE_NS_ASSERTIONS = NO; 292 | ENABLE_STRICT_OBJC_MSGSEND = YES; 293 | GCC_C_LANGUAGE_STANDARD = gnu99; 294 | GCC_NO_COMMON_BLOCKS = YES; 295 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 296 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 297 | GCC_WARN_UNDECLARED_SELECTOR = YES; 298 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 299 | GCC_WARN_UNUSED_FUNCTION = YES; 300 | GCC_WARN_UNUSED_VARIABLE = YES; 301 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 302 | MTL_ENABLE_DEBUG_INFO = NO; 303 | SDKROOT = iphoneos; 304 | VALIDATE_PRODUCT = YES; 305 | }; 306 | name = Release; 307 | }; 308 | C2B3C4161BA2671B002344AE /* Debug */ = { 309 | isa = XCBuildConfiguration; 310 | buildSettings = { 311 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 312 | INFOPLIST_FILE = ARTextViewAutocompletionExampleSwift/Info.plist; 313 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 314 | PRODUCT_NAME = "$(TARGET_NAME)"; 315 | SWIFT_OBJC_BRIDGING_HEADER = "ARTextViewAutocompletionExampleSwift/ARTextViewAutocompletionExampleSwift-bridging-header.h"; 316 | }; 317 | name = Debug; 318 | }; 319 | C2B3C4171BA2671B002344AE /* Release */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 323 | INFOPLIST_FILE = ARTextViewAutocompletionExampleSwift/Info.plist; 324 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 325 | PRODUCT_NAME = "$(TARGET_NAME)"; 326 | SWIFT_OBJC_BRIDGING_HEADER = "ARTextViewAutocompletionExampleSwift/ARTextViewAutocompletionExampleSwift-bridging-header.h"; 327 | }; 328 | name = Release; 329 | }; 330 | /* End XCBuildConfiguration section */ 331 | 332 | /* Begin XCConfigurationList section */ 333 | C2B3C3F11BA2671B002344AE /* Build configuration list for PBXProject "ARTextViewAutocompletionExampleSwift" */ = { 334 | isa = XCConfigurationList; 335 | buildConfigurations = ( 336 | C2B3C4131BA2671B002344AE /* Debug */, 337 | C2B3C4141BA2671B002344AE /* Release */, 338 | ); 339 | defaultConfigurationIsVisible = 0; 340 | defaultConfigurationName = Release; 341 | }; 342 | C2B3C4151BA2671B002344AE /* Build configuration list for PBXNativeTarget "ARTextViewAutocompletionExampleSwift" */ = { 343 | isa = XCConfigurationList; 344 | buildConfigurations = ( 345 | C2B3C4161BA2671B002344AE /* Debug */, 346 | C2B3C4171BA2671B002344AE /* Release */, 347 | ); 348 | defaultConfigurationIsVisible = 0; 349 | defaultConfigurationName = Release; 350 | }; 351 | /* End XCConfigurationList section */ 352 | }; 353 | rootObject = C2B3C3EE1BA2671B002344AE /* Project object */; 354 | } 355 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift/ARTextViewAutocompletionExampleSwift-bridging-header.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ARTextViewAutocompletionExampleSwift 4 | // 5 | // Created by Lucas Farah on 9/10/15. 6 | // Copyright (c) 2015 Lucas Farah. All rights reserved. 7 | // 8 | 9 | #import "ARAutocompleteTextView.h" 10 | #import "AREmailAutocompleteTextView.h" 11 | #import "ARTwitterAutocompleteTextView.h" 12 | #import "ARAutocompleteManager.h" 13 | 14 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ARTextViewAutocompletionExampleSwift 4 | // 5 | // Created by Lucas Farah on 9/10/15. 6 | // Copyright (c) 2015 Lucas Farah. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(application: UIApplication) { 23 | // 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. 24 | // 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. 25 | } 26 | 27 | func applicationDidEnterBackground(application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(application: UIApplication) { 33 | // 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. 34 | } 35 | 36 | func applicationDidBecomeActive(application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 75 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 116 | 122 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | farah.lucas.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ARTextViewAutocompletionExampleSwift/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // ARTextViewAutocompletionExampleSwift 4 | // 5 | // Created by Lucas Farah on 9/10/15. 6 | // Copyright (c) 2015 Lucas Farah. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UITableViewController,UITextViewDelegate { 12 | 13 | @IBOutlet weak var emailTextView: AREmailAutocompleteTextView! 14 | @IBOutlet weak var allTextView: ARTwitterAutocompleteTextView! 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | // Set a default data source for all ARAutocompleteTextView instances. Otherwise, you can specify the data source on individual text fields via the autocompleteDataSource property or use my default AREmailAutocompleteTextView and ARTwitterAutocompleteTextView like in this sample 19 | ARAutocompleteTextView.setDefaultAutocompleteDataSource(ARAutocompleteManager.sharedManager()) 20 | 21 | // Dismiss the keyboard when the user taps outside of a text field 22 | let singleTap = UITapGestureRecognizer(target: self, action: "handleSingleTap") 23 | self.view.addGestureRecognizer(singleTap) 24 | 25 | } 26 | 27 | func handleSingleTap() 28 | { 29 | self.emailTextView.resignFirstResponder() 30 | self.allTextView.resignFirstResponder() 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Classes/ARAutocompleteTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARAutocompleteTextView.h 3 | // alexruperez 4 | // 5 | // Created by Alejandro Rupérez on 11/29/12. 6 | // Inspired by DOautocompleteTextView by DoAT. 7 | // 8 | // Copyright (c) 2013 alexruperez. All rights reserved. 9 | // 10 | 11 | #import 12 | 13 | @class ARAutocompleteTextView; 14 | 15 | @protocol ARAutocompleteDataSource 16 | 17 | - (NSString*)textView:(ARAutocompleteTextView*)textView 18 | completionForPrefix:(NSString*)prefix 19 | ignoreCase:(BOOL)ignoreCase; 20 | 21 | @end 22 | 23 | @protocol ARAutocompleteTextViewDelegate 24 | 25 | @optional 26 | - (void)autoCompleteTextViewDidAutoComplete:(ARAutocompleteTextView *)autoCompleteField; 27 | - (void)autoCompleteTextView:(ARAutocompleteTextView *)autocompleteTextView didChangeAutocompleteText:(NSString *)autocompleteText; 28 | 29 | @end 30 | 31 | @interface ARAutocompleteTextView : UITextView 32 | 33 | /* 34 | * Designated programmatic initializer (also compatible with Interface Builder) 35 | */ 36 | - (id)initWithFrame:(CGRect)frame; 37 | 38 | /* 39 | * Autocomplete behavior 40 | */ 41 | @property (nonatomic, assign) NSUInteger autocompleteType; // Can be used by the dataSource to provide different types of autocomplete behavior 42 | @property (nonatomic, assign) BOOL autocompleteDisabled; 43 | @property (nonatomic, assign) BOOL ignoreCase; 44 | @property (nonatomic, assign) id autoCompleteTextViewDelegate; 45 | @property (nonatomic, assign) id innerTextViewDelegate; 46 | 47 | /* 48 | * Configure text field appearance 49 | */ 50 | @property (nonatomic, strong) UILabel *autocompleteLabel; 51 | - (void)setFont:(UIFont *)font; 52 | @property (nonatomic, assign) CGPoint autocompleteTextOffset; 53 | 54 | /* 55 | * Specify a data source responsible for determining autocomplete text. 56 | */ 57 | @property (nonatomic, assign) id autocompleteDataSource; 58 | + (void)setDefaultAutocompleteDataSource:(id)dataSource; 59 | 60 | /* 61 | * Subclassing: 62 | */ 63 | - (CGRect)autocompleteRectForBounds:(CGRect)bounds; // Override to alter the position of the autocomplete text 64 | - (void)setupAutocompleteTextView; // Override to perform setup tasks. Don't forget to call super. 65 | 66 | /* 67 | * Refresh the autocomplete text manually (useful if you want the text to change while the user isn't editing the text) 68 | */ 69 | - (void)forceRefreshAutocompleteText; 70 | 71 | @end -------------------------------------------------------------------------------- /Classes/ARAutocompleteTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARAutocompleteTextView.m 3 | // alexruperez 4 | // 5 | // Created by Alejandro Rupérez on 11/29/12. 6 | // Inspired by DOautocompleteTextView by DoAT. 7 | // 8 | // Copyright (c) 2013 alexruperez. All rights reserved. 9 | // 10 | 11 | #import "ARAutocompleteTextView.h" 12 | 13 | static NSObject *DefaultAutocompleteDataSource = nil; 14 | 15 | @interface ARAutocompleteTextView () 16 | 17 | @property (nonatomic, strong) NSString *autocompleteString; 18 | @property (nonatomic, assign) BOOL autocompleted; 19 | 20 | @end 21 | 22 | @implementation ARAutocompleteTextView 23 | 24 | - (id)initWithFrame:(CGRect)frame 25 | { 26 | self = [super initWithFrame:frame]; 27 | if (self) 28 | { 29 | [self setupAutocompleteTextView]; 30 | } 31 | return self; 32 | } 33 | 34 | - (void)awakeFromNib 35 | { 36 | [super awakeFromNib]; 37 | 38 | [self setupAutocompleteTextView]; 39 | } 40 | 41 | - (void)dealloc 42 | { 43 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:self]; 44 | } 45 | 46 | - (void)setupAutocompleteTextView 47 | { 48 | [super setDelegate:self]; 49 | 50 | self.autocompleteLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 51 | self.autocompleteLabel.font = self.font; 52 | self.autocompleteLabel.backgroundColor = [UIColor clearColor]; 53 | self.autocompleteLabel.textColor = [UIColor lightGrayColor]; 54 | 55 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 56 | NSLineBreakMode lineBreakMode = NSLineBreakByClipping; 57 | #else 58 | UILineBreakMode lineBreakMode = UILineBreakModeClip; 59 | #endif 60 | 61 | self.autocompleteLabel.lineBreakMode = lineBreakMode; 62 | self.autocompleteLabel.hidden = YES; 63 | [self addSubview:self.autocompleteLabel]; 64 | [self bringSubviewToFront:self.autocompleteLabel]; 65 | 66 | self.autocompleteString = @""; 67 | self.autocompleted = NO; 68 | 69 | self.ignoreCase = YES; 70 | 71 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ar_textDidChange:) name:UITextViewTextDidChangeNotification object:self]; 72 | } 73 | 74 | #pragma mark - Configuration 75 | 76 | + (void)setDefaultAutocompleteDataSource:(id)dataSource 77 | { 78 | DefaultAutocompleteDataSource = dataSource; 79 | } 80 | 81 | - (void)setFont:(UIFont *)font 82 | { 83 | [super setFont:font]; 84 | [self.autocompleteLabel setFont:font]; 85 | } 86 | 87 | - (void)setDelegate:(id)delegate 88 | { 89 | self.innerTextViewDelegate = delegate; 90 | } 91 | 92 | #pragma mark - UIResponder 93 | 94 | - (BOOL)becomeFirstResponder 95 | { 96 | if (!self.autocompleteDisabled) 97 | { 98 | self.autocompleteLabel.hidden = NO; 99 | } 100 | 101 | return [super becomeFirstResponder]; 102 | } 103 | 104 | - (BOOL)resignFirstResponder 105 | { 106 | if (!self.autocompleteDisabled) 107 | { 108 | self.autocompleteLabel.hidden = YES; 109 | 110 | if ([self commitAutocompleteText]) { 111 | // Only notify if committing autocomplete actually changed the text. 112 | 113 | 114 | // This is necessary because committing the autocomplete text changes the text field's text, but for some reason UITextView doesn't post the UITextViewTextDidChangeNotification notification on its own 115 | [[NSNotificationCenter defaultCenter] postNotificationName:UITextViewTextDidChangeNotification object:self]; 116 | } 117 | } 118 | return [super resignFirstResponder]; 119 | } 120 | 121 | #pragma mark - Autocomplete Logic 122 | 123 | - (CGRect)autocompleteRectForBounds:(CGRect)bounds 124 | { 125 | CGRect caretRect = [self caretRectForPosition:self.selectedTextRange.start]; 126 | 127 | CGRect returnRect = CGRectMake(caretRect.origin.x + 1.0f, caretRect.origin.y, self.frame.size.width, caretRect.size.height); 128 | 129 | return returnRect; 130 | } 131 | 132 | - (void)ar_textDidChange:(NSNotification*)notification 133 | { 134 | [self refreshAutocompleteText]; 135 | } 136 | 137 | - (void)updateAutocompleteLabel 138 | { 139 | [self.autocompleteLabel setText:self.autocompleteString]; 140 | [self.autocompleteLabel sizeToFit]; 141 | [self.autocompleteLabel setFrame: [self autocompleteRectForBounds:self.bounds]]; 142 | 143 | if ([self.autoCompleteTextViewDelegate respondsToSelector:@selector(autoCompleteTextView:didChangeAutocompleteText:)]) { 144 | [self.autoCompleteTextViewDelegate autoCompleteTextView:self didChangeAutocompleteText:self.autocompleteString]; 145 | } 146 | } 147 | 148 | - (void)refreshAutocompleteText 149 | { 150 | if (!self.autocompleteDisabled) 151 | { 152 | id dataSource = nil; 153 | 154 | if ([self.autocompleteDataSource respondsToSelector:@selector(textView:completionForPrefix:ignoreCase:)]) 155 | { 156 | dataSource = (id )self.autocompleteDataSource; 157 | } 158 | else if ([DefaultAutocompleteDataSource respondsToSelector:@selector(textView:completionForPrefix:ignoreCase:)]) 159 | { 160 | dataSource = DefaultAutocompleteDataSource; 161 | } 162 | 163 | if (dataSource) 164 | { 165 | self.autocompleteString = [dataSource textView:self completionForPrefix:self.text ignoreCase:self.ignoreCase]; 166 | 167 | if (self.autocompleteString.length > 0) 168 | { 169 | if ([self.text hasSuffix:@" "]) { 170 | self.text = [self.text substringToIndex:[self.text length] - 1]; 171 | [self autocompleteText:self]; 172 | } 173 | } 174 | 175 | [self updateAutocompleteLabel]; 176 | } 177 | } 178 | } 179 | 180 | - (BOOL)commitAutocompleteText 181 | { 182 | NSString *currentText = self.text; 183 | if (self.autocompleteString && [self.autocompleteString isEqualToString:@""] == NO 184 | && self.autocompleteDisabled == NO) 185 | { 186 | self.text = [NSString stringWithFormat:@"%@%@", self.text, self.autocompleteString]; 187 | 188 | self.autocompleteString = @""; 189 | [self updateAutocompleteLabel]; 190 | 191 | if ([self.autoCompleteTextViewDelegate respondsToSelector:@selector(autoCompleteTextViewDidAutoComplete:)]) { 192 | [self.autoCompleteTextViewDelegate autoCompleteTextViewDidAutoComplete:self]; 193 | } 194 | } 195 | return ![currentText isEqualToString:self.text]; 196 | } 197 | 198 | - (void)forceRefreshAutocompleteText 199 | { 200 | [self refreshAutocompleteText]; 201 | } 202 | 203 | #pragma mark - UITextView Delegate Methods 204 | 205 | - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 206 | { 207 | if (self.autocompleted) { 208 | if ([text isEqualToString:@". "]) { 209 | self.autocompleted = NO; 210 | return NO; 211 | } 212 | } 213 | 214 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textView:shouldChangeTextInRange:replacementText:)]) { 215 | return [self.innerTextViewDelegate textView:textView shouldChangeTextInRange:range replacementText:text]; 216 | } 217 | return YES; 218 | } 219 | 220 | - (BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange 221 | { 222 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textView:shouldInteractWithTextAttachment:inRange:)]) { 223 | return [self.innerTextViewDelegate textView:textView shouldInteractWithTextAttachment:textAttachment inRange:characterRange]; 224 | } 225 | return YES; 226 | } 227 | 228 | - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange 229 | { 230 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textView:shouldInteractWithURL:inRange:)]) { 231 | return [self.innerTextViewDelegate textView:textView shouldInteractWithURL:URL inRange:characterRange]; 232 | } 233 | return YES; 234 | } 235 | 236 | - (void)textViewDidBeginEditing:(UITextView *)textView 237 | { 238 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textViewDidBeginEditing:)]) { 239 | [self.innerTextViewDelegate textViewDidBeginEditing:textView]; 240 | } 241 | } 242 | 243 | - (void)textViewDidChange:(UITextView *)textView 244 | { 245 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textViewDidChange:)]) { 246 | [self.innerTextViewDelegate textViewDidChange:textView]; 247 | } 248 | } 249 | 250 | - (void)textViewDidChangeSelection:(UITextView *)textView 251 | { 252 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textViewDidChangeSelection:)]) { 253 | [self.innerTextViewDelegate textViewDidChangeSelection:textView]; 254 | } 255 | } 256 | 257 | - (void)textViewDidEndEditing:(UITextView *)textView 258 | { 259 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textViewDidEndEditing:)]) { 260 | [self.innerTextViewDelegate textViewDidEndEditing:textView]; 261 | } 262 | } 263 | 264 | - (BOOL)textViewShouldBeginEditing:(UITextView *)textView 265 | { 266 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textViewShouldBeginEditing:)]) { 267 | return [self.innerTextViewDelegate textViewShouldBeginEditing:textView]; 268 | } 269 | return YES; 270 | } 271 | 272 | - (BOOL)textViewShouldEndEditing:(UITextView *)textView 273 | { 274 | if (self.innerTextViewDelegate && [self.innerTextViewDelegate respondsToSelector:@selector(textViewShouldEndEditing:)]) { 275 | return [self.innerTextViewDelegate textViewShouldEndEditing:textView]; 276 | } 277 | return YES; 278 | } 279 | 280 | #pragma mark - Accessors 281 | 282 | - (void)setAutocompleteString:(NSString *)autocompleteString 283 | { 284 | _autocompleteString = autocompleteString; 285 | } 286 | 287 | #pragma mark - Private Methods 288 | 289 | - (void)autocompleteText:(id)sender 290 | { 291 | if (!self.autocompleteDisabled) 292 | { 293 | self.autocompleteLabel.hidden = NO; 294 | 295 | [self commitAutocompleteText]; 296 | 297 | self.autocompleted = YES; 298 | 299 | // This is necessary because committing the autocomplete text changes the text field's text, but for some reason UITextView doesn't post the UITextViewTextDidChangeNotification notification on its own 300 | [[NSNotificationCenter defaultCenter] postNotificationName:UITextViewTextDidChangeNotification object:self]; 301 | } 302 | } 303 | 304 | @end 305 | -------------------------------------------------------------------------------- /Classes/AREmailAutocompleteTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // AREmailAutocompleteTextView.h 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 2/27/13. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import "ARAutocompleteTextView.h" 10 | 11 | @interface AREmailAutocompleteTextView : ARAutocompleteTextView 12 | 13 | @property (nonatomic, copy) NSArray *emailDomains; // modify to use your own custom list of email domains 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/AREmailAutocompleteTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // AREmailAutocompleteTextView.m 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 2/27/13. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import "AREmailAutocompleteTextView.h" 10 | 11 | @implementation AREmailAutocompleteTextView 12 | 13 | - (void)setupAutocompleteTextView 14 | { 15 | [super setupAutocompleteTextView]; 16 | 17 | // Default email domains to suggest 18 | self.emailDomains = @[ @"gmail.com", @"yahoo.com", @"hotmail.com", @"aol.com", @"comcast.net", @"me.com", @"msn.com", @"live.com", @"sbcglobal.net", @"ymail.com", @"att.net", @"mac.com", @"cox.net", @"verizon.net", @"hotmail.co.uk", @"bellsouth.net", @"rocketmail.com", @"aim.com", @"yahoo.co.uk", @"earthlink.net", @"charter.net", @"optonline.net", @"shaw.ca", @"yahoo.ca", @"googlemail.com", @"mail.com", @"qq.com", @"btinternet.com", @"mail.ru", @"live.co.uk", @"naver.com", @"rogers.com", @"juno.com", @"yahoo.com.tw", @"live.ca", @"walla.com", @"163.com", @"roadrunner.com", @"telus.net", @"embarqmail.com", @"hotmail.fr", @"pacbell.net", @"sky.com", @"sympatico.ca", @"cfl.rr.com", @"tampabay.rr.com", @"q.com", @"yahoo.co.in", @"yahoo.fr", @"hotmail.ca", @"windstream.net", @"hotmail.it", @"web.de", @"asu.edu", @"gmx.de", @"gmx.com", @"insightbb.com", @"netscape.net", @"icloud.com", @"frontier.com", @"126.com", @"hanmail.net", @"suddenlink.net", @"netzero.net", @"mindspring.com", @"ail.com", @"windowslive.com", @"netzero.com", @"yahoo.com.hk", @"yandex.ru", @"mchsi.com", @"cableone.net", @"yahoo.com.cn", @"yahoo.es", @"yahoo.com.br", @"cornell.edu", @"ucla.edu", @"us.army.mil", @"excite.com", @"ntlworld.com", @"usc.edu", @"nate.com", @"outlook.com", @"nc.rr.com", @"prodigy.net", @"wi.rr.com", @"videotron.ca", @"yahoo.it", @"yahoo.com.au", @"umich.edu", @"ameritech.net", @"libero.it", @"yahoo.de", @"rochester.rr.com", @"cs.com", @"frontiernet.net", @"swbell.net", @"msu.edu", @"ptd.net", @"proxymail.facebook.com", @"hotmail.es", @"austin.rr.com", @"nyu.edu", @"sina.com", @"centurytel.net", @"usa.net", @"nycap.rr.com", @"uci.edu", @"hotmail.de", @"yahoo.com.sg", @"email.arizona.edu", @"yahoo.com.mx", @"ufl.edu", @"bigpond.com", @"unlv.nevada.edu", @"yahoo.cn", @"ca.rr.com", @"google.com", @"yahoo.co.id", @"inbox.com", @"fuse.net", @"hawaii.rr.com", @"talktalk.net", @"gmx.net", @"walla.co.il", @"ucdavis.edu", @"carolina.rr.com", @"comcast.com", @"live.fr", @"blueyonder.co.uk", @"live.cn", @"cogeco.ca", @"abv.bg", @"tds.net", @"centurylink.net", @"yahoo.com.vn", @"uol.com.br", @"osu.edu", @"san.rr.com", @"rcn.com", @"umn.edu", @"live.nl", @"live.com.au", @"tx.rr.com", @"eircom.net", @"sasktel.net", @"post.harvard.edu", @"snet.net", @"wowway.com", @"live.it", @"att.com", @"vt.edu", @"rambler.ru", @"temple.edu", @"cinci.rr.com", @"alexruperez.com"]; 19 | 20 | self.autocompleteDataSource = self; 21 | } 22 | 23 | #pragma mark - ARAutocompleteDataSource 24 | 25 | - (NSString *)textView:(ARAutocompleteTextView *)textView completionForPrefix:(NSString *)prefix ignoreCase:(BOOL)ignoreCase 26 | { 27 | // Check that text field contains an @ 28 | NSRange atSignRange = [prefix rangeOfString:@"@"]; 29 | if (atSignRange.location == NSNotFound) 30 | { 31 | return @""; 32 | } 33 | 34 | // Stop autocomplete if user types dot after domain 35 | NSString *domainAndTLD = [prefix substringFromIndex:atSignRange.location]; 36 | NSRange rangeOfDot = [domainAndTLD rangeOfString:@""]; 37 | if (rangeOfDot.location != NSNotFound) 38 | { 39 | return @""; 40 | } 41 | 42 | NSArray *textComponents = [prefix componentsSeparatedByString:@"@"]; 43 | 44 | if ([textComponents count] > 1) 45 | { 46 | NSString *lastText = [[textComponents lastObject] stringByReplacingOccurrencesOfString:@" " withString:@""]; 47 | // If no domain is entered, use the first domain in the list 48 | if ([lastText length] == 0) 49 | { 50 | return [self.emailDomains objectAtIndex:0]; 51 | } 52 | 53 | NSString *stringToLookFor = lastText; 54 | if (ignoreCase) 55 | { 56 | stringToLookFor = [stringToLookFor lowercaseString]; 57 | } 58 | 59 | for (NSString *stringFromReference in self.emailDomains) 60 | { 61 | NSString *stringToCompare = stringFromReference; 62 | if (ignoreCase) 63 | { 64 | stringToCompare = [stringToCompare lowercaseString]; 65 | } 66 | 67 | if ([stringToCompare hasPrefix:stringToLookFor]) 68 | { 69 | return [stringFromReference stringByReplacingCharactersInRange:[stringToCompare rangeOfString:stringToLookFor] withString:@""]; 70 | } 71 | 72 | } 73 | } 74 | 75 | return @""; 76 | } 77 | 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /Classes/ARTwitterAutocompleteTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARTwitterAutocompleteTextView.h 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 2/27/13. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import "ARAutocompleteTextView.h" 10 | 11 | @interface ARTwitterAutocompleteTextView : ARAutocompleteTextView 12 | 13 | @property (nonatomic, copy) NSArray *autocomplete; // modify to use your own custom list 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/ARTwitterAutocompleteTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARTwitterAutocompleteTextView.m 3 | // ARTextViewAutocompletionExample 4 | // 5 | // Created by Alejandro Rupérez on 2/27/13. 6 | // Copyright (c) 2013 alexruperez. All rights reserved. 7 | // 8 | 9 | #import "ARTwitterAutocompleteTextView.h" 10 | 11 | @implementation ARTwitterAutocompleteTextView 12 | 13 | - (void)setupAutocompleteTextView 14 | { 15 | [super setupAutocompleteTextView]; 16 | 17 | // Default list to suggest 18 | self.autocomplete = @[ @"@alexruperez", @"@feverapp", @"@JavierQuerol", @"#alexruperez", @"#fever", @"#google", @"#facebook", @"#twitter", @"#hashtag" ]; 19 | 20 | self.autocompleteDataSource = self; 21 | } 22 | 23 | #pragma mark - ARAutocompleteDataSource 24 | 25 | - (NSString *)textView:(ARAutocompleteTextView *)textView completionForPrefix:(NSString *)prefix ignoreCase:(BOOL)ignoreCase 26 | { 27 | // Check that text field contains an @ or # 28 | NSString *contains = @"@"; 29 | NSRange atSignRange = [prefix rangeOfString:@"@" options:NSBackwardsSearch]; 30 | NSRange atSignRange2 = [prefix rangeOfString:@"#" options:NSBackwardsSearch]; 31 | 32 | if ((atSignRange.location == NSNotFound) && (atSignRange2.location == NSNotFound)) { 33 | return @""; 34 | } 35 | 36 | if ((atSignRange.location == NSNotFound) || (((atSignRange.location != NSNotFound) && (atSignRange2.location != NSNotFound)) && (atSignRange2.location > atSignRange.location))) { 37 | atSignRange = atSignRange2; 38 | contains = @"#"; 39 | } 40 | 41 | NSArray *textComponents = [prefix componentsSeparatedByString:contains]; 42 | 43 | if ([textComponents count] > 1) 44 | { 45 | NSString *lastText = [[textComponents lastObject] stringByReplacingOccurrencesOfString:@" " withString:@""]; 46 | // Use the first in the list by default 47 | if ([lastText length] == 0) 48 | { 49 | for (NSString *stringFromReference in self.autocomplete) 50 | { 51 | if ([stringFromReference hasPrefix:contains]) 52 | { 53 | return [stringFromReference stringByReplacingOccurrencesOfString:contains withString:@""]; 54 | } 55 | } 56 | } 57 | 58 | NSString *stringToLookFor = lastText; 59 | if (ignoreCase) 60 | { 61 | stringToLookFor = [stringToLookFor lowercaseString]; 62 | } 63 | 64 | for (NSString *stringFromReference in self.autocomplete) 65 | { 66 | NSString *stringToCompare = [stringFromReference stringByReplacingOccurrencesOfString:contains withString:@""]; 67 | if (ignoreCase) 68 | { 69 | stringToCompare = [stringToCompare lowercaseString]; 70 | } 71 | 72 | if ([stringToCompare hasPrefix:stringToLookFor]) 73 | { 74 | NSRange range = [stringToCompare rangeOfString:stringToLookFor]; 75 | range.length++; 76 | return [stringFromReference stringByReplacingCharactersInRange:range withString:@""]; 77 | } 78 | 79 | } 80 | } 81 | 82 | return @""; 83 | 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013 alexruperez 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # ARAutocompleteTextView 3 | [![Twitter](http://img.shields.io/badge/contact-@alexruperez-blue.svg?style=flat)](http://twitter.com/alexruperez) 4 | [![GitHub Issues](http://img.shields.io/github/issues/alexruperez/ARAutocompleteTextView.svg?style=flat)](http://github.com/alexruperez/ARAutocompleteTextView/issues) 5 | [![Version Status](http://img.shields.io/cocoapods/v/ARAutocompleteTextView.svg?style=flat)](http://cocoadocs.org/docsets/ARAutocompleteTextView) 6 | [![License Status](http://img.shields.io/cocoapods/l/ARAutocompleteTextView.svg?style=flat)](http://cocoadocs.org/docsets/ARAutocompleteTextView) 7 | [![Platform Status](http://img.shields.io/cocoapods/p/ARAutocompleteTextView.svg?style=flat)](http://cocoadocs.org/docsets/ARAutocompleteTextView) 8 | [![Analytics](https://ga-beacon.appspot.com/UA-55329295-1/ARAutocompleteTextView/readme?pixel)](https://github.com/igrigorik/ga-beacon) 9 | 10 | ## Overview 11 | 12 | ARAutocompleteTextView is a subclass of UITextView that automatically displays text suggestions in real-time. This is perfect for automatically suggesting the domain as a user types an email address, #hashtag or @handle. 13 | 14 | ARTextViewAutocompletion 15 | 16 | # Usage 17 | 18 | ## Installation 19 | 20 | ### Add the following files to your project: 21 | * `ARAutocompleteTextView.m` 22 | * `ARAutocompleteTextView.h` 23 | * `ARAutocompleteManager.m` 24 | * `ARAutocompleteManager.h` 25 | 26 | ## Quickstart Guide 27 | 28 | Create an `ARAutocompleteTextView` instance exactly as as you would `UITextView`. You can do eith either programmitcally or in Interface Builder. Programmatically, this looks like: 29 | 30 | ##### Objective C 31 | 32 | ARAutocompleteTextView* textField = [[ARAutocompleteTextView alloc] initWithFrame:CGRectMake(0,0,100,31)]; 33 | 34 | ##### Swift 35 | 36 | let textField = ARAutocompleteTextView(frame: CGRectMake(0, 0, 100, 31)) 37 | 38 | 39 | 40 | The data source is the brains of the autocomplete logic. If you just want to autocomplete email addresses, #hashtags or @handles, use `ARAutocompleteManager` from the example project as follows: 41 | 42 | ##### Objective-C 43 | textField.autocompleteDataSource = [ARAutocompleteManager sharedManager]; 44 | textField.autocompleteType = ARAutocompleteTypeEmail; 45 | 46 | ##### Swift 47 | textField.autocompleteDataSource = ARAutocompleteManager.sharedManager() 48 | textField.autocompleteType = ARAutocompleteType.Mail 49 | 50 | 51 | ## Customization 52 | 53 | ### Autocompletion Data Source 54 | 55 | `ARAutocompleteManager` (included in the example project) provides email address autocompletion out of the box. It comes with a list of the top email domains. You may want to tailor this list of email domains to match your own customers, or you may want to write autocomplete logic for a different type of text view (in the demo, names of colors are autocompleted). 56 | 57 | Alternatively, you may wish to create your own data source class and user the `autocompleteType` property to differentiate between textviews with different data types. A `ARAutocompleteTextView`'s data source must implement the following method, as part of the `ARAutocompleteDataSource` protocol. 58 | 59 | - (NSString *)textField:(ARAutocompleteTextView*)textField completionForPrefix:(NSString *)prefix 60 | 61 | You may also set a default `dataSource` for all instances of `ARAutocompleteTextView`. In the example project, we use a `ARAutocompleteManager` singleton: 62 | 63 | [autocompleteTextOffset setDefaultAutocompleteDataSource:[ARAutocompleteManager sharedManager]]; 64 | 65 | ### Positioning and Formatting 66 | 67 | To adjust the position of the autocomplete label by a fixed amount, set `autocompleteTextOffset`: 68 | 69 | textField.autocompleteTextOffset = CGPointMake(10.0, 10.0); 70 | 71 | For more dynamic positioning of the autocomplete label, subclass `ARAutocompleteTextView` and override `- (CGRect)autocompleteRectForBounds:(CGRect)bounds`. 72 | 73 | To adjust the properties (i.e. `font`, `textColor`) of the autocomplete label, do so via the `[AutocompleteTextField autocompleteLabel] property. 74 | 75 | textField.autocompleteLabel.textColor = [UIColor grayColor]; 76 | 77 | ## Event Listening 78 | 79 | In addition to observing the standard `UITextView` notifications (i.e. `UITextViewTextDidChangeNotification` and friends), you can use `[ARAutocompleteTextView autoCompleteTextFieldDelegate]` to listen for certain events. This is particularly useful if you are collecting analytics. 80 | 81 | # Etc. 82 | 83 | * Use this in your apps whenever you can, particularly email addresses -- your users will appreciate it! 84 | * Contributions are very welcome. 85 | * Attribution is appreciated (let's spread the word!), but not mandatory. 86 | 87 | ## Use it? Love/hate it? 88 | 89 | Tweet the author @alexruperez, and check out alexruperez's blog: http://alexruperez.com 90 | 91 | ## Other Links 92 | 93 | [code4app Review](http://code4app.net/ios/ARAutocompleteTextView/528d8d86cb7e8464178b4e35) 94 | 95 | [Cocoa Controls](http://cocoacontrols.com/controls/arautocompletetextview) 96 | --------------------------------------------------------------------------------