├── .gitignore ├── .npmignore ├── RCTTextInputUtils.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── KanzakiMirai.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── KanzakiMirai.xcuserdatad │ └── xcschemes │ │ ├── RCTKeyboardToolbar.xcscheme │ │ └── xcschememanagement.plist │ └── libinlu.xcuserdatad │ └── xcschemes │ ├── RCTKeyboardToolbar.xcscheme │ └── xcschememanagement.plist ├── RCTTextInputUtils ├── RCTKeyboardDatePicker.h ├── RCTKeyboardDatePicker.m ├── RCTKeyboardPicker.h ├── RCTKeyboardPicker.m ├── RCTKeyboardToolbar.h ├── RCTKeyboardToolbar.m ├── RCTTextFieldExtension.h ├── RCTTextFieldExtension.m ├── RCTTextViewExtension.h └── RCTTextViewExtension.m ├── README.md ├── index.ios.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /RCTTextInputUtils.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C9C74BC31CC16F3E00F3BD12 /* RCTKeyboardDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = C9C74BC21CC16F3E00F3BD12 /* RCTKeyboardDatePicker.m */; }; 11 | EA8030411BF2BCDD002D36C5 /* RCTKeyboardPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = EA80303A1BF2BCDD002D36C5 /* RCTKeyboardPicker.m */; }; 12 | EA8030421BF2BCDD002D36C5 /* RCTKeyboardToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = EA80303C1BF2BCDD002D36C5 /* RCTKeyboardToolbar.m */; }; 13 | EA8030431BF2BCDD002D36C5 /* RCTTextFieldExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = EA80303E1BF2BCDD002D36C5 /* RCTTextFieldExtension.m */; }; 14 | EA8030441BF2BCDD002D36C5 /* RCTTextViewExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = EA8030401BF2BCDD002D36C5 /* RCTTextViewExtension.m */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXCopyFilesBuildPhase section */ 18 | EADF3C811BEE147600DCD186 /* CopyFiles */ = { 19 | isa = PBXCopyFilesBuildPhase; 20 | buildActionMask = 2147483647; 21 | dstPath = "include/$(PRODUCT_NAME)"; 22 | dstSubfolderSpec = 16; 23 | files = ( 24 | ); 25 | runOnlyForDeploymentPostprocessing = 0; 26 | }; 27 | /* End PBXCopyFilesBuildPhase section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | C9C74BC11CC16E0E00F3BD12 /* RCTKeyboardDatePicker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RCTKeyboardDatePicker.h; path = RCTTextInputUtils/RCTKeyboardDatePicker.h; sourceTree = ""; }; 31 | C9C74BC21CC16F3E00F3BD12 /* RCTKeyboardDatePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTKeyboardDatePicker.m; path = RCTTextInputUtils/RCTKeyboardDatePicker.m; sourceTree = ""; }; 32 | EA8030391BF2BCDD002D36C5 /* RCTKeyboardPicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTKeyboardPicker.h; path = RCTTextInputUtils/RCTKeyboardPicker.h; sourceTree = ""; }; 33 | EA80303A1BF2BCDD002D36C5 /* RCTKeyboardPicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTKeyboardPicker.m; path = RCTTextInputUtils/RCTKeyboardPicker.m; sourceTree = ""; }; 34 | EA80303B1BF2BCDD002D36C5 /* RCTKeyboardToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTKeyboardToolbar.h; path = RCTTextInputUtils/RCTKeyboardToolbar.h; sourceTree = ""; }; 35 | EA80303C1BF2BCDD002D36C5 /* RCTKeyboardToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTKeyboardToolbar.m; path = RCTTextInputUtils/RCTKeyboardToolbar.m; sourceTree = ""; }; 36 | EA80303D1BF2BCDD002D36C5 /* RCTTextFieldExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTTextFieldExtension.h; path = RCTTextInputUtils/RCTTextFieldExtension.h; sourceTree = ""; }; 37 | EA80303E1BF2BCDD002D36C5 /* RCTTextFieldExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTTextFieldExtension.m; path = RCTTextInputUtils/RCTTextFieldExtension.m; sourceTree = ""; }; 38 | EA80303F1BF2BCDD002D36C5 /* RCTTextViewExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTTextViewExtension.h; path = RCTTextInputUtils/RCTTextViewExtension.h; sourceTree = ""; }; 39 | EA8030401BF2BCDD002D36C5 /* RCTTextViewExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTTextViewExtension.m; path = RCTTextInputUtils/RCTTextViewExtension.m; sourceTree = ""; }; 40 | EADF3C831BEE147600DCD186 /* libRCTKeyboardToolbar.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTKeyboardToolbar.a; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | EADF3C801BEE147600DCD186 /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | ); 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | /* End PBXFrameworksBuildPhase section */ 52 | 53 | /* Begin PBXGroup section */ 54 | EA8030381BF2BCD1002D36C5 /* RCTTextInputUtils */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | EA8030391BF2BCDD002D36C5 /* RCTKeyboardPicker.h */, 58 | EA80303A1BF2BCDD002D36C5 /* RCTKeyboardPicker.m */, 59 | EA80303B1BF2BCDD002D36C5 /* RCTKeyboardToolbar.h */, 60 | EA80303C1BF2BCDD002D36C5 /* RCTKeyboardToolbar.m */, 61 | EA80303D1BF2BCDD002D36C5 /* RCTTextFieldExtension.h */, 62 | EA80303E1BF2BCDD002D36C5 /* RCTTextFieldExtension.m */, 63 | EA80303F1BF2BCDD002D36C5 /* RCTTextViewExtension.h */, 64 | EA8030401BF2BCDD002D36C5 /* RCTTextViewExtension.m */, 65 | C9C74BC11CC16E0E00F3BD12 /* RCTKeyboardDatePicker.h */, 66 | C9C74BC21CC16F3E00F3BD12 /* RCTKeyboardDatePicker.m */, 67 | ); 68 | name = RCTTextInputUtils; 69 | sourceTree = ""; 70 | }; 71 | EADF3C7A1BEE147600DCD186 = { 72 | isa = PBXGroup; 73 | children = ( 74 | EA8030381BF2BCD1002D36C5 /* RCTTextInputUtils */, 75 | EADF3C841BEE147600DCD186 /* Products */, 76 | ); 77 | sourceTree = ""; 78 | }; 79 | EADF3C841BEE147600DCD186 /* Products */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | EADF3C831BEE147600DCD186 /* libRCTKeyboardToolbar.a */, 83 | ); 84 | name = Products; 85 | sourceTree = ""; 86 | }; 87 | /* End PBXGroup section */ 88 | 89 | /* Begin PBXNativeTarget section */ 90 | EADF3C821BEE147600DCD186 /* RCTKeyboardToolbar */ = { 91 | isa = PBXNativeTarget; 92 | buildConfigurationList = EADF3C8C1BEE147600DCD186 /* Build configuration list for PBXNativeTarget "RCTKeyboardToolbar" */; 93 | buildPhases = ( 94 | EADF3C7F1BEE147600DCD186 /* Sources */, 95 | EADF3C801BEE147600DCD186 /* Frameworks */, 96 | EADF3C811BEE147600DCD186 /* CopyFiles */, 97 | ); 98 | buildRules = ( 99 | ); 100 | dependencies = ( 101 | ); 102 | name = RCTKeyboardToolbar; 103 | productName = RCTKeyboardToolbar; 104 | productReference = EADF3C831BEE147600DCD186 /* libRCTKeyboardToolbar.a */; 105 | productType = "com.apple.product-type.library.static"; 106 | }; 107 | /* End PBXNativeTarget section */ 108 | 109 | /* Begin PBXProject section */ 110 | EADF3C7B1BEE147600DCD186 /* Project object */ = { 111 | isa = PBXProject; 112 | attributes = { 113 | LastSwiftUpdateCheck = 0700; 114 | LastUpgradeCheck = 0700; 115 | ORGANIZATIONNAME = DickyT; 116 | TargetAttributes = { 117 | EADF3C821BEE147600DCD186 = { 118 | CreatedOnToolsVersion = 7.0; 119 | }; 120 | }; 121 | }; 122 | buildConfigurationList = EADF3C7E1BEE147600DCD186 /* Build configuration list for PBXProject "RCTTextInputUtils" */; 123 | compatibilityVersion = "Xcode 3.2"; 124 | developmentRegion = English; 125 | hasScannedForEncodings = 0; 126 | knownRegions = ( 127 | en, 128 | ); 129 | mainGroup = EADF3C7A1BEE147600DCD186; 130 | productRefGroup = EADF3C841BEE147600DCD186 /* Products */; 131 | projectDirPath = ""; 132 | projectRoot = ""; 133 | targets = ( 134 | EADF3C821BEE147600DCD186 /* RCTKeyboardToolbar */, 135 | ); 136 | }; 137 | /* End PBXProject section */ 138 | 139 | /* Begin PBXSourcesBuildPhase section */ 140 | EADF3C7F1BEE147600DCD186 /* Sources */ = { 141 | isa = PBXSourcesBuildPhase; 142 | buildActionMask = 2147483647; 143 | files = ( 144 | EA8030421BF2BCDD002D36C5 /* RCTKeyboardToolbar.m in Sources */, 145 | EA8030411BF2BCDD002D36C5 /* RCTKeyboardPicker.m in Sources */, 146 | EA8030431BF2BCDD002D36C5 /* RCTTextFieldExtension.m in Sources */, 147 | EA8030441BF2BCDD002D36C5 /* RCTTextViewExtension.m in Sources */, 148 | C9C74BC31CC16F3E00F3BD12 /* RCTKeyboardDatePicker.m in Sources */, 149 | ); 150 | runOnlyForDeploymentPostprocessing = 0; 151 | }; 152 | /* End PBXSourcesBuildPhase section */ 153 | 154 | /* Begin XCBuildConfiguration section */ 155 | EADF3C8A1BEE147600DCD186 /* Debug */ = { 156 | isa = XCBuildConfiguration; 157 | buildSettings = { 158 | ALWAYS_SEARCH_USER_PATHS = NO; 159 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 160 | CLANG_CXX_LIBRARY = "libc++"; 161 | CLANG_ENABLE_MODULES = YES; 162 | CLANG_ENABLE_OBJC_ARC = YES; 163 | CLANG_WARN_BOOL_CONVERSION = YES; 164 | CLANG_WARN_CONSTANT_CONVERSION = YES; 165 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 166 | CLANG_WARN_EMPTY_BODY = YES; 167 | CLANG_WARN_ENUM_CONVERSION = YES; 168 | CLANG_WARN_INT_CONVERSION = YES; 169 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 170 | CLANG_WARN_UNREACHABLE_CODE = YES; 171 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 172 | COPY_PHASE_STRIP = NO; 173 | DEBUG_INFORMATION_FORMAT = dwarf; 174 | ENABLE_STRICT_OBJC_MSGSEND = YES; 175 | ENABLE_TESTABILITY = YES; 176 | GCC_C_LANGUAGE_STANDARD = gnu99; 177 | GCC_DYNAMIC_NO_PIC = NO; 178 | GCC_NO_COMMON_BLOCKS = YES; 179 | GCC_OPTIMIZATION_LEVEL = 0; 180 | GCC_PREPROCESSOR_DEFINITIONS = ( 181 | "DEBUG=1", 182 | "$(inherited)", 183 | ); 184 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 185 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 186 | GCC_WARN_UNDECLARED_SELECTOR = YES; 187 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 188 | GCC_WARN_UNUSED_FUNCTION = YES; 189 | GCC_WARN_UNUSED_VARIABLE = YES; 190 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 191 | MTL_ENABLE_DEBUG_INFO = YES; 192 | ONLY_ACTIVE_ARCH = YES; 193 | SDKROOT = iphoneos; 194 | }; 195 | name = Debug; 196 | }; 197 | EADF3C8B1BEE147600DCD186 /* Release */ = { 198 | isa = XCBuildConfiguration; 199 | buildSettings = { 200 | ALWAYS_SEARCH_USER_PATHS = NO; 201 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 202 | CLANG_CXX_LIBRARY = "libc++"; 203 | CLANG_ENABLE_MODULES = YES; 204 | CLANG_ENABLE_OBJC_ARC = YES; 205 | CLANG_WARN_BOOL_CONVERSION = YES; 206 | CLANG_WARN_CONSTANT_CONVERSION = YES; 207 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 208 | CLANG_WARN_EMPTY_BODY = YES; 209 | CLANG_WARN_ENUM_CONVERSION = YES; 210 | CLANG_WARN_INT_CONVERSION = YES; 211 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 212 | CLANG_WARN_UNREACHABLE_CODE = YES; 213 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 214 | COPY_PHASE_STRIP = NO; 215 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 216 | ENABLE_NS_ASSERTIONS = NO; 217 | ENABLE_STRICT_OBJC_MSGSEND = YES; 218 | GCC_C_LANGUAGE_STANDARD = gnu99; 219 | GCC_NO_COMMON_BLOCKS = YES; 220 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 221 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 222 | GCC_WARN_UNDECLARED_SELECTOR = YES; 223 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 224 | GCC_WARN_UNUSED_FUNCTION = YES; 225 | GCC_WARN_UNUSED_VARIABLE = YES; 226 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 227 | MTL_ENABLE_DEBUG_INFO = NO; 228 | SDKROOT = iphoneos; 229 | VALIDATE_PRODUCT = YES; 230 | }; 231 | name = Release; 232 | }; 233 | EADF3C8D1BEE147600DCD186 /* Debug */ = { 234 | isa = XCBuildConfiguration; 235 | buildSettings = { 236 | CLANG_ENABLE_MODULES = YES; 237 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 238 | ENABLE_TESTABILITY = NO; 239 | GENERATE_PROFILING_CODE = NO; 240 | HEADER_SEARCH_PATHS = ( 241 | "$(inherited)", 242 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 243 | "$(SRCROOT)/../../React/**", 244 | "$(SRCROOT)/../../node_modules/react-native/React/**", 245 | "$(SRCROOT)/../../node_modules/react-native/Libraries/**", 246 | ); 247 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 248 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 249 | OTHER_LDFLAGS = "-ObjC"; 250 | PRODUCT_NAME = "$(TARGET_NAME)"; 251 | SKIP_INSTALL = YES; 252 | SWIFT_OBJC_BRIDGING_HEADER = "RCTKeyboardToolbar-Bridging-Header.h"; 253 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 254 | }; 255 | name = Debug; 256 | }; 257 | EADF3C8E1BEE147600DCD186 /* Release */ = { 258 | isa = XCBuildConfiguration; 259 | buildSettings = { 260 | CLANG_ENABLE_MODULES = YES; 261 | COPY_PHASE_STRIP = YES; 262 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 263 | ENABLE_TESTABILITY = NO; 264 | GENERATE_PROFILING_CODE = NO; 265 | HEADER_SEARCH_PATHS = ( 266 | "$(inherited)", 267 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 268 | "$(SRCROOT)/../../React/**", 269 | "$(SRCROOT)/../../node_modules/react-native/React/**", 270 | "$(SRCROOT)/../../node_modules/react-native/Libraries/**", 271 | ); 272 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 273 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 274 | OTHER_LDFLAGS = "-ObjC"; 275 | PRODUCT_NAME = "$(TARGET_NAME)"; 276 | SKIP_INSTALL = YES; 277 | SWIFT_OBJC_BRIDGING_HEADER = "RCTKeyboardToolbar-Bridging-Header.h"; 278 | }; 279 | name = Release; 280 | }; 281 | /* End XCBuildConfiguration section */ 282 | 283 | /* Begin XCConfigurationList section */ 284 | EADF3C7E1BEE147600DCD186 /* Build configuration list for PBXProject "RCTTextInputUtils" */ = { 285 | isa = XCConfigurationList; 286 | buildConfigurations = ( 287 | EADF3C8A1BEE147600DCD186 /* Debug */, 288 | EADF3C8B1BEE147600DCD186 /* Release */, 289 | ); 290 | defaultConfigurationIsVisible = 0; 291 | defaultConfigurationName = Release; 292 | }; 293 | EADF3C8C1BEE147600DCD186 /* Build configuration list for PBXNativeTarget "RCTKeyboardToolbar" */ = { 294 | isa = XCConfigurationList; 295 | buildConfigurations = ( 296 | EADF3C8D1BEE147600DCD186 /* Debug */, 297 | EADF3C8E1BEE147600DCD186 /* Release */, 298 | ); 299 | defaultConfigurationIsVisible = 0; 300 | defaultConfigurationName = Release; 301 | }; 302 | /* End XCConfigurationList section */ 303 | }; 304 | rootObject = EADF3C7B1BEE147600DCD186 /* Project object */; 305 | } 306 | -------------------------------------------------------------------------------- /RCTTextInputUtils.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RCTTextInputUtils.xcodeproj/project.xcworkspace/xcuserdata/KanzakiMirai.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DickyT/react-native-textinput-utils/ad4fdb8c499b1d9d60c8dab4a420bdaa9f80cbe4/RCTTextInputUtils.xcodeproj/project.xcworkspace/xcuserdata/KanzakiMirai.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RCTTextInputUtils.xcodeproj/xcuserdata/KanzakiMirai.xcuserdatad/xcschemes/RCTKeyboardToolbar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /RCTTextInputUtils.xcodeproj/xcuserdata/KanzakiMirai.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RCTKeyboardToolbar.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | EADF3C821BEE147600DCD186 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /RCTTextInputUtils.xcodeproj/xcuserdata/libinlu.xcuserdatad/xcschemes/RCTKeyboardToolbar.xcscheme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DickyT/react-native-textinput-utils/ad4fdb8c499b1d9d60c8dab4a420bdaa9f80cbe4/RCTTextInputUtils.xcodeproj/xcuserdata/libinlu.xcuserdatad/xcschemes/RCTKeyboardToolbar.xcscheme -------------------------------------------------------------------------------- /RCTTextInputUtils.xcodeproj/xcuserdata/libinlu.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DickyT/react-native-textinput-utils/ad4fdb8c499b1d9d60c8dab4a420bdaa9f80cbe4/RCTTextInputUtils.xcodeproj/xcuserdata/libinlu.xcuserdatad/xcschemes/xcschememanagement.plist -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTKeyboardDatePicker.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface RCTKeyboardDatePicker : UIDatePicker 4 | 5 | @property (nonatomic, retain) id callbackObject; 6 | @property (nonatomic, assign) SEL callbackSeletor; 7 | 8 | - (void)setOptions:(NSDictionary*)options; 9 | - (void)setCallbackObject:(id)anObject withSelector:(SEL)selector; 10 | 11 | @end -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTKeyboardDatePicker.m: -------------------------------------------------------------------------------- 1 | 2 | #import "RCTKeyboardDatePicker.h" 3 | #import 4 | #import "RCTDatePickerManager.h" 5 | 6 | @implementation RCTKeyboardDatePicker 7 | 8 | - (instancetype)initWithFrame:(CGRect)frame 9 | { 10 | if ((self = [super initWithFrame:frame])) { 11 | [self addTarget:self action:@selector(didChange) 12 | forControlEvents:UIControlEventValueChanged]; 13 | } 14 | return self; 15 | } 16 | 17 | - (void)setCallbackObject:(id)anObject withSelector:(SEL)selector 18 | { 19 | self.callbackObject = anObject; 20 | self.callbackSeletor = selector; 21 | } 22 | 23 | - (void)didChange 24 | { 25 | [self.callbackObject performSelector:self.callbackSeletor withObject:self]; 26 | } 27 | 28 | -(void)setOptions:(NSDictionary *)options 29 | { 30 | self.minimumDate = [RCTConvert NSDate:[options objectForKey:@"minimumDate"]]; 31 | self.maximumDate = [RCTConvert NSDate:[options objectForKey:@"maximumDate"]]; 32 | self.minuteInterval = [RCTConvert NSInteger:[options objectForKey:@"minuteInterval"]]; 33 | self.datePickerMode = [RCTConvert UIDatePickerMode:[options objectForKey:@"mode"]]; 34 | self.timeZone = [RCTConvert NSTimeZone:[options objectForKey:@"timeZoneOffsetInMinutes"]]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTKeyboardPicker.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyboardPicker.h 3 | // RCTKeyboardToolbar 4 | // 5 | // Created by Kanzaki Mirai on 11/9/15. 6 | // Copyright © 2015 DickyT. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RCTKeyboardPicker : UIPickerView 13 | 14 | @property (nonatomic, retain) NSMutableArray* viewData; 15 | @property (nonatomic, retain) id callbackObject; 16 | @property (nonatomic, assign) SEL callbackSeletor; 17 | 18 | - (void)setCallbackObject:(id)anObject withSelector:(SEL)selector; 19 | 20 | - (void)setData:(NSArray*)viewData; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTKeyboardPicker.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyboardPicker.m 3 | // RCTKeyboardToolbar 4 | // 5 | // Created by Kanzaki Mirai on 11/9/15. 6 | // Copyright © 2015 DickyT. All rights reserved. 7 | // 8 | #import "RCTKeyboardPicker.h" 9 | 10 | @implementation RCTKeyboardPicker 11 | 12 | - (id)init 13 | { 14 | self = [super init]; 15 | self.delegate = self; 16 | self.dataSource = self; 17 | 18 | self.viewData = [[NSMutableArray alloc]init]; 19 | return self; 20 | } 21 | 22 | - (void)setCallbackObject:(id)anObject withSelector:(SEL)selector 23 | { 24 | self.callbackObject = anObject; 25 | self.callbackSeletor = selector; 26 | } 27 | 28 | - (void)setData:(NSArray*)viewData 29 | { 30 | self.viewData = [[NSMutableArray alloc]initWithArray:viewData]; 31 | } 32 | 33 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 34 | { 35 | return 1; 36 | } 37 | 38 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 39 | { 40 | return [self.viewData count]; 41 | } 42 | 43 | - (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 44 | { 45 | NSString *currentData = [self.viewData objectAtIndex:row]; 46 | return currentData; 47 | } 48 | 49 | - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 50 | { 51 | [self.callbackObject performSelector:self.callbackSeletor withObject:self]; 52 | } 53 | 54 | @end -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTKeyboardToolbar.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyboardToolbar.h 3 | // RCTKeyboardToolbar 4 | // 5 | // Created by Kanzaki Mirai on 11/7/15. 6 | // Copyright © 2015 DickyT. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RCTKeyboardToolbar : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTKeyboardToolbar.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTKeyboardToolbar.m 3 | // RCTKeyboardToolbar 4 | // 5 | // Created by Kanzaki Mirai on 11/7/15. 6 | // Copyright © 2015 DickyT. All rights reserved. 7 | // 8 | 9 | #import "RCTKeyboardToolbar.h" 10 | 11 | #import 12 | #import 13 | #import "RCTTextField.h" 14 | #import "RCTTextView.h" 15 | #import 16 | #import 17 | #import "RCTKeyboardPicker.h" 18 | #import "RCTTextViewExtension.h" 19 | #import "RCTDatePicker.h" 20 | #import "RCTDatePickerManager.h" 21 | #import "RCTKeyboardDatePicker.h" 22 | 23 | @implementation RCTKeyboardToolbar 24 | 25 | #pragma mark - 26 | 27 | @synthesize bridge = _bridge; 28 | 29 | RCT_EXPORT_MODULE() 30 | 31 | - (dispatch_queue_t)methodQueue { 32 | return self.bridge.uiManager.methodQueue; 33 | } 34 | 35 | RCT_EXPORT_METHOD(configure:(nonnull NSNumber *)reactNode 36 | options:(NSDictionary *)options 37 | callback:(RCTResponseSenderBlock)callback) { 38 | [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry ) { 39 | 40 | UIView *view = viewRegistry[reactNode]; 41 | if (!view) { 42 | RCTLogError(@"RCTKeyboardToolbar: TAG #%@ NOT FOUND", reactNode); 43 | return; 44 | } 45 | 46 | // The convert is little bit dangerous, change it if you are going to fock the project 47 | // Or do not assign any non-common property between UITextView and UITextView 48 | UITextField *textView; 49 | if ([view class] == [RCTTextView class]) { 50 | RCTTextView *reactNativeTextView = ((RCTTextView *)view); 51 | textView = [reactNativeTextView getTextView]; 52 | } 53 | else { 54 | RCTTextField *reactNativeTextView = ((RCTTextField *)view); 55 | textView = [reactNativeTextView textField]; 56 | } 57 | 58 | if (options[@"tintColor"]) { 59 | NSLog(@"tintColor is %@", options[@"tintColor"]); 60 | textView.tintColor = [RCTConvert UIColor:options[@"tintColor"]]; 61 | } 62 | 63 | UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 0, 0)]; 64 | 65 | NSInteger toolbarStyle = [RCTConvert NSInteger:options[@"barStyle"]]; 66 | numberToolbar.barStyle = toolbarStyle; 67 | 68 | NSString *leftButtonText = [RCTConvert NSString:options[@"leftButtonText"]]; 69 | NSString *rightButtonText = [RCTConvert NSString:options[@"rightButtonText"]]; 70 | 71 | NSNumber *currentUid = [RCTConvert NSNumber:options[@"uid"]]; 72 | 73 | NSMutableArray *toolbarItems = [NSMutableArray array]; 74 | if (![leftButtonText isEqualToString:@""]) { 75 | UIBarButtonItem *leftItem = [[UIBarButtonItem alloc]initWithTitle:leftButtonText style:UIBarButtonItemStyleBordered target:self action:@selector(keyboardCancel:)]; 76 | leftItem.tag = [currentUid intValue]; 77 | [toolbarItems addObject:leftItem]; 78 | } 79 | if (![leftButtonText isEqualToString:@""] && ![rightButtonText isEqualToString:@""]) { 80 | [toolbarItems addObject:[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]]; 81 | } 82 | if (![rightButtonText isEqualToString:@""]) { 83 | UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]initWithTitle:rightButtonText style:UIBarButtonItemStyleDone target:self action:@selector(keyboardDone:)]; 84 | rightItem.tag = [currentUid intValue]; 85 | [toolbarItems addObject:rightItem]; 86 | } 87 | numberToolbar.items = toolbarItems; 88 | 89 | NSArray *pickerData = [RCTConvert NSArray:options[@"pickerViewData"]]; 90 | 91 | if (pickerData.count > 0) { 92 | RCTKeyboardPicker *pickerView = [[RCTKeyboardPicker alloc]init]; 93 | pickerView.tag = [currentUid intValue]; 94 | [pickerView setCallbackObject:self withSelector:@selector(valueSelected:)]; 95 | [pickerView setData:pickerData]; 96 | textView.inputView = pickerView; 97 | } 98 | 99 | NSDictionary *datePickerViewData = [RCTConvert NSDictionary:options[@"datePickerOptions"]]; 100 | if(datePickerViewData != nil){ 101 | RCTKeyboardDatePicker *datePickerView = [[RCTKeyboardDatePicker alloc] init]; 102 | datePickerView.tag = [currentUid intValue]; 103 | [datePickerView setCallbackObject:self withSelector:@selector(dateSelected:)]; 104 | [datePickerView setOptions:datePickerViewData]; 105 | textView.inputView = datePickerView; 106 | } 107 | 108 | [numberToolbar sizeToFit]; 109 | textView.inputAccessoryView = numberToolbar; 110 | 111 | callback(@[[NSNull null], [currentUid stringValue]]); 112 | }]; 113 | } 114 | 115 | RCT_EXPORT_METHOD(dismissKeyboard:(nonnull NSNumber *)reactNode) { 116 | [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry ) { 117 | 118 | UIView *view = viewRegistry[reactNode]; 119 | if (!view) { 120 | RCTLogError(@"RCTKeyboardToolbar: TAG #%@ NOT FOUND", reactNode); 121 | return; 122 | } 123 | RCTTextField *textView = ((RCTTextField *)view); 124 | 125 | dispatch_async(dispatch_get_main_queue(), ^{ 126 | [textView resignFirstResponder]; 127 | }); 128 | }]; 129 | } 130 | 131 | RCT_EXPORT_METHOD(moveCursorToLast:(nonnull NSNumber *)reactNode) { 132 | [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry ) { 133 | 134 | UIView *view = viewRegistry[reactNode]; 135 | if (!view) { 136 | RCTLogError(@"RCTKeyboardToolbar: TAG #%@ NOT FOUND", reactNode); 137 | return; 138 | } 139 | RCTTextField *textView = ((RCTTextField *)view); 140 | 141 | dispatch_async(dispatch_get_main_queue(), ^{ 142 | UITextPosition *position = [textView.backedTextInputView endOfDocument]; 143 | textView.backedTextInputView.selectedTextRange = [textView.backedTextInputView textRangeFromPosition:position toPosition:position]; 144 | }); 145 | }]; 146 | } 147 | 148 | RCT_EXPORT_METHOD(setSelectedTextRange:(nonnull NSNumber *)reactNode 149 | options:(NSDictionary *)options) { 150 | [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry ) { 151 | 152 | UIView *view = viewRegistry[reactNode]; 153 | if (!view) { 154 | RCTLogError(@"RCTKeyboardToolbar: TAG #%@ NOT FOUND", reactNode); 155 | return; 156 | } 157 | RCTTextField *textView = ((RCTTextField *)view); 158 | 159 | NSNumber *startPosition = [RCTConvert NSNumber:options[@"start"]]; 160 | NSNumber *endPosition = [RCTConvert NSNumber:options[@"length"]]; 161 | 162 | NSRange range = NSMakeRange([startPosition integerValue], [endPosition integerValue]); 163 | 164 | dispatch_async(dispatch_get_main_queue(), ^{ 165 | UITextPosition *from = [textView.backedTextInputView positionFromPosition:[textView.backedTextInputView beginningOfDocument] offset:range.location]; 166 | UITextPosition *to = [textView.backedTextInputView positionFromPosition:from offset:range.length]; 167 | [textView.backedTextInputView setSelectedTextRange:[textView.backedTextInputView textRangeFromPosition:from toPosition:to]]; 168 | }); 169 | }]; 170 | } 171 | 172 | RCT_EXPORT_METHOD(setDate:(nonnull NSNumber *)reactNode 173 | options:(NSDictionary *)options) { 174 | [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { 175 | 176 | UIView *view = viewRegistry[reactNode]; 177 | if (!view) { 178 | RCTLogError(@"RCTKeyboardToolbar: TAG #%@ NOT FOUND", reactNode); 179 | return; 180 | } 181 | 182 | UIDatePicker *datePicker = ((UIDatePicker *)view.inputView); 183 | 184 | NSDate *date = [RCTConvert NSDate:options[@"date"]]; 185 | 186 | [datePicker setDate: date]; 187 | }]; 188 | } 189 | 190 | RCT_EXPORT_METHOD(setPickerRowByIndex:(nonnull NSNumber *)reactNode 191 | options:(NSDictionary *)options) { 192 | [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { 193 | 194 | UIView *view = viewRegistry[reactNode]; 195 | if (!view) { 196 | RCTLogError(@"RCTKeyboardToolbar: TAG #%@ NOT FOUND", reactNode); 197 | return; 198 | } 199 | 200 | UITextField *textView; 201 | if ([view class] == [RCTTextView class]) { 202 | RCTTextView *reactNativeTextView = ((RCTTextView *)view); 203 | textView = [reactNativeTextView getTextView]; 204 | } 205 | else { 206 | RCTTextField *reactNativeTextView = ((RCTTextField *)view); 207 | textView = [reactNativeTextView textField]; 208 | } 209 | 210 | UIPickerView *pickerView = ((UIPickerView *)textView.inputView); 211 | 212 | NSInteger index = [RCTConvert NSInteger:options[@"index"]]; 213 | 214 | [pickerView selectRow: index inComponent:0 animated:YES]; 215 | }]; 216 | } 217 | 218 | RCT_EXPORT_METHOD(reloadPickerData:(nonnull NSNumber *)reactNode 219 | options:(NSDictionary *)options) { 220 | [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { 221 | 222 | UIView *view = viewRegistry[reactNode]; 223 | if (!view) { 224 | RCTLogError(@"RCTKeyboardToolbar: TAG #%@ NOT FOUND", reactNode); 225 | return; 226 | } 227 | 228 | RCTKeyboardPicker *pickerView = ((RCTKeyboardPicker *)view.inputView); 229 | 230 | NSArray *data = [RCTConvert NSArray:options[@"data"]]; 231 | 232 | [pickerView setData: data]; 233 | [pickerView reloadAllComponents]; 234 | 235 | }]; 236 | } 237 | 238 | -(void)dateSelected:(RCTKeyboardDatePicker*)sender 239 | { 240 | NSNumber *currentUid = [NSNumber numberWithLong:sender.tag]; 241 | [self.bridge.eventDispatcher sendAppEventWithName:@"TUKeyboardDatePickerViewDidSelected" 242 | body:@{@"currentUid" : [currentUid stringValue], @"selectedDate": @(sender.date.timeIntervalSince1970 * 1000.0)}]; 243 | } 244 | 245 | - (void)valueSelected:(RCTKeyboardPicker*)sender 246 | { 247 | NSNumber *selectedIndex = [NSNumber numberWithLong:[sender selectedRowInComponent:0]]; 248 | NSLog(@"Selected %d", [selectedIndex intValue]); 249 | NSNumber *currentUid = [NSNumber numberWithLong:sender.tag]; 250 | [self.bridge.eventDispatcher sendAppEventWithName:@"TUKeyboardPickerViewDidSelected" 251 | body:@{@"currentUid" : [currentUid stringValue], @"selectedIndex": [selectedIndex stringValue]}]; 252 | } 253 | 254 | - (void)keyboardCancel:(UIBarButtonItem*)sender 255 | { 256 | NSNumber *currentUid = [NSNumber numberWithLong:sender.tag]; 257 | [self.bridge.eventDispatcher sendAppEventWithName:@"TUKeyboardToolbarDidTouchOnCancel" 258 | body:@([currentUid intValue])]; 259 | } 260 | 261 | - (void)keyboardDone:(UIBarButtonItem*)sender 262 | { 263 | NSNumber *currentUid = [NSNumber numberWithLong:sender.tag]; 264 | [self.bridge.eventDispatcher sendAppEventWithName:@"TUKeyboardToolbarDidTouchOnDone" 265 | body:@([currentUid intValue])]; 266 | } 267 | 268 | @end 269 | -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTTextFieldExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTTextFieldExtension.h 3 | // RCTKeyboardToolbar 4 | // 5 | // Created by Kanzaki Mirai on 11/10/15. 6 | // Copyright © 2015 DickyT. All rights reserved. 7 | // 8 | 9 | #import "RCTTextField.h" 10 | 11 | @interface RCTTextField (RCTTextFieldExtension) 12 | 13 | - (void)setSelectedRange:(NSRange)range; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTTextFieldExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTTextFieldExtension.m 3 | // RCTKeyboardToolbar 4 | // 5 | // Created by Kanzaki Mirai on 11/10/15. 6 | // Copyright © 2015 DickyT. All rights reserved. 7 | // 8 | 9 | #import "RCTTextFieldExtension.h" 10 | 11 | @implementation RCTTextField (RCTTextFieldExtension) 12 | 13 | - (void)setSelectedRange:(NSRange)range 14 | { 15 | UITextPosition* beginning = self.backedTextInputView.beginningOfDocument; 16 | UITextPosition* startPosition = [self.backedTextInputView positionFromPosition:beginning offset:range.location]; 17 | UITextPosition* endPosition = [self.backedTextInputView positionFromPosition:beginning offset:range.location + range.length]; 18 | UITextRange* selectionRange = [self.backedTextInputView textRangeFromPosition:startPosition toPosition:endPosition]; 19 | [self.backedTextInputView setSelectedTextRange:selectionRange]; 20 | } 21 | 22 | - (void)invalidateInputAccessoryView { 23 | // prevents input accessory being removed 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTTextViewExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTTextViewExtension.h 3 | // RCTTextInputUtils 4 | // 5 | // Created by Kanzaki Mirai on 11/10/15. 6 | // Copyright © 2015 DickyT. All rights reserved. 7 | // 8 | 9 | #import "RCTTextView.h" 10 | 11 | @interface RCTTextView (RCTTextViewExtension) 12 | 13 | - (UITextField *)getTextView; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RCTTextInputUtils/RCTTextViewExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTTextViewExtension.m 3 | // RCTTextInputUtils 4 | // 5 | // Created by Kanzaki Mirai on 11/10/15. 6 | // Copyright © 2015 DickyT. All rights reserved. 7 | // 8 | 9 | #import "RCTTextViewExtension.h" 10 | 11 | @implementation RCTTextView (RCTTextViewExtension) 12 | 13 | - (UITextField *)getTextView 14 | { 15 | // actually returns a UITextView, I wrote this way just want to surpress warnings 16 | return [self valueForKey:@"_textView"]; 17 | } 18 | 19 | - (void)invalidateInputAccessoryView { 20 | // prevents input accessory being removed 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## React Native TextInput Utils (iOS only) 2 | [![npm version](https://badge.fury.io/js/react-native-textinput-utils.svg)](https://badge.fury.io/js/react-native-textinput-utils) 3 | [![MIT](https://img.shields.io/dub/l/vibe-d.svg)]() 4 | 5 | **THIS PACKAGE IS NO LONGER MAINTAINED SINCE 2018 AND DOES NOT WORK WITH LATEST REACT NATIVE** 6 | 7 | A react native extendsion which allows you to control TextInput better. 8 | 9 | The original name is [react-native-keyboard-toolbar](http://github.com/DickyT/react-native-keyboard-toolbar), because the latest add some features, I think the old name is not suitable for this package. 10 | 11 | ![react-native-textinput-utils](https://cloud.githubusercontent.com/assets/4535844/11055687/f2652524-874f-11e5-96f0-333c6bc4ba1c.gif) 12 | 13 | ## Timeline 14 | 0.3.7 - Now support RN 0.40 15 | 16 | 0.3.6 - New feature of `setPickerRowByIndex` and `reloadPickerData` by @DaveAdams88 17 | 18 | 0.2.5 - Added the fully support of `multiline` `` 19 | 20 | 0.2.1 - Added the support of `tintColor`, which can set the cursor color 21 | 22 | 0.2 - Added the support of `dismissKeyboard`, `moveCursorToLast` and `setSelection` 23 | 24 | 0.1 - Added the support of setting an `UIPickerView` as the `inputView` 25 | 26 | 27 | ## What can I do? 28 | 29 | 1. Adding `UITabBarItem`(s) into the keyboard of `` 30 | 2. Adding a `UIPickerView` as a default keyboard of `` 31 | 3. Setting the selection area or cursor using only two parameters, which are `start` and `length` 32 | 33 | *The `PickerIOS` Component in React Native 0.13 cannot be styled well outside `NavigatorIOS`* 34 | 35 | 36 | ## Limitation 37 | This extension does not support `` with `multiline={true}`, and I need some time to figure out. If you got some idea, it will really welcome to send me a PR. 38 | 39 | ## Installation 40 | 41 | __I am still very simple to use__ 42 | 43 | ```cd``` to your React Native project directory and run 44 | 45 | ```npm install react-native-textinput-utils --save``` 46 | 47 | ## How to run 48 | 49 | ### Runing the demo 50 | Download and open the `RCTTextInputUtilsDemo.xcodeproj` file, and runs. 51 | 52 | ### Using this package in other project 53 | You might need to add the `es7.classProperties` into your `PROJECT_ROOT/npm_modules/react-native/packager/transformer.js` and `PROJECT_ROOT/npm_modules/react-native/packager/react-packager/.babelrc` 54 | 55 | ## iOS configuration 56 | 57 | 1. In XCode, in the project navigator right click `Libraries` ➜ `Add Files to [your project's name]` 58 | 2. Go to `node_modules` ➜ `react-native-textinput-utils` and *ADD* `RCTTextInputUtils.xcodeproj` 59 | 3. Drag `libRCTKeyboardToolbar.a` (from 'Products' under RCTTextInputUtils.xcodeproj) into `General` ➜ `Linked Frameworks and Libraries` phase. (GIF below) 60 | 5. Run your project (`Cmd+R`) 61 | 62 | ![RCTTextInputUtilsGuide](https://cloud.githubusercontent.com/assets/4535844/11019656/9ff660dc-85d8-11e5-9823-b4437f498a77.gif) 63 | 64 | ## Basic Usage 65 | ```jsx 66 | var RCTKeyboardToolbarTextInput = require('react-native-textinput-utils'); 67 | ``` 68 | 69 | ```jsx 70 | dismissKeyboard()} 74 | onDone={(dismissKeyboard)=>dismissKeyboard()} 75 | /> 76 | ``` 77 | 78 | ### If you want a UIPickerView 79 | ```jsx 80 | var pickerViewData = [ 81 | { 82 | label: 'One', 83 | value: 'ValueOne' 84 | }, 85 | { 86 | label: 'Two', 87 | value: 'ValueTwo' 88 | }, 89 | { 90 | label: 'Three', 91 | value: 'ValueThree' 92 | } 93 | ]; 94 | ``` 95 | ```jsx 96 | {console.log(`selected ${selectedIndex}`)}} 99 | ... 100 | /> 101 | ``` 102 | 103 | ### If you want to set the cursor color 104 | ```jsx 105 | 109 | ``` 110 | 111 | ### If you want to set the selection area 112 | ```jsx 113 | 117 | ``` 118 | and you can call 119 | ```jsx 120 | this.refs['reference'].setSelection(start, length); 121 | ``` 122 | 123 | #### Or you just want to simply move the cursor to the last 124 | ```jsx 125 | this.refs['reference'].moveCursorToLast(); 126 | ``` 127 | 128 | #### Or dismiss the keyboard whenever you want 129 | ```jsx 130 | this.refs['reference'].dismissKeyboard(); 131 | ``` 132 | 133 | ## Configurations 134 | The **``** object can take the following props: 135 | 136 | ### Basic Parameters 137 | - `leftButtonText`: The text in the *left-side* `UIToolBarItem`, if this value is empty, the UIToolBarItem on the *left* side will not be created 138 | - `rightButtonText`: The text in the *right-side* `UIToolBarItem`, if this value is empty, the UIToolBarItem on the *right* side will not be created 139 | - `onCancel`: The callback function of *left-side* `UIToolBarItem` 140 | - `onDone`: The callback function of *right-side* `UIToolBarItem` 141 | - `tintColor`: The cusor color 142 | 143 | And both `onCancel` and `onDone` will passing an function back, if you call that function, the keyboard will be dismissed. 144 | 145 | ```jsx 146 | function onCancel_Or_onDone(dismissKeyboardFunction) { 147 | console.log(`I will dismiss the keyboard`); 148 | dismissKeyboardFunction(); 149 | } 150 | ``` 151 | 152 | ### PickerView related Parameters 153 | - `pickerViewData`: The data source of the `PickerView`, should be an `Array`, which each element is an `Object`, and the `label` in each `Object` will be display in the `PickerView` 154 | - `onPickerSelect`: The callback function when user picks an option, will pass the `selectedIndex` back, you can use this index to reference back to your data `Array` 155 | 156 | ```jsx 157 | function onPickerSelectCallback(selectedIndex) { 158 | console.log(`Selected Index is ${selectedIndex}`); 159 | } 160 | ``` 161 | 162 | __If you set the `ref` props of this Component, you can reference it back after `constructor` is called. You can use `this.refs[YOUR_REFERENCE]` to access the Component`s related methods.__ 163 | 164 | Here is the methods 165 | - `dismissKeyboard`: If you want to dismiss the keyboard or the `UIPickerView`, just call it. 166 | - `moveCursorToLast`: If you want to set the cursor to the last position, just call it. 167 | - `setSelection(start, length)`: Using this method, you can set the selection area, if the `length = 0`, the cursor will move to `start` position. 168 | 169 | Questions 170 | -------------- 171 | If something is undocumented here, and it is not clear with you, feel free to create an issue here, I will tried my best to answer you. 172 | 173 | Anything else 174 | -------------- 175 | Feel free to request new features, just create an issue. 176 | It will be very welcome to pull request for me. 177 | 178 | My email ```me@idickyt.com``` 179 | 180 | Facebook [Dicky Tsang](https://www.facebook.com/idickytsang) 181 | 182 | Sina Weibo ```@桐乃``` 183 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const {findNodeHandle, TextInput, NativeAppEventEmitter, NativeModules: { 6 | KeyboardToolbar 7 | }, processColor, Keyboard} = require('react-native'); 8 | 9 | class RCTKeyboardToolbarHelper { 10 | static sharedInstance = new RCTKeyboardToolbarHelper(); 11 | constructor() { 12 | this.counter = 0; 13 | this.callbackList = {}; 14 | } 15 | static getUid() { 16 | return RCTKeyboardToolbarHelper.sharedInstance.counter++; 17 | } 18 | static setCallback(key, value) { 19 | RCTKeyboardToolbarHelper.sharedInstance.callbackList[key] = value; 20 | } 21 | static getCallback(key) { 22 | return RCTKeyboardToolbarHelper.sharedInstance.callbackList[key]; 23 | } 24 | static clearCallback(key) { 25 | delete RCTKeyboardToolbarHelper.sharedInstance.callbackList[key]; 26 | } 27 | } 28 | 29 | NativeAppEventEmitter.addListener('TUKeyboardToolbarDidTouchOnCancel', (currentUid) => { 30 | let eventHandler = RCTKeyboardToolbarHelper.getCallback(currentUid).onCancel; 31 | if (eventHandler) { 32 | eventHandler(); 33 | } 34 | }); 35 | 36 | NativeAppEventEmitter.addListener('TUKeyboardToolbarDidTouchOnDone', (currentUid) => { 37 | let eventHandler = RCTKeyboardToolbarHelper.getCallback(currentUid).onDone; 38 | if (eventHandler) { 39 | eventHandler(); 40 | } 41 | }); 42 | 43 | NativeAppEventEmitter.addListener('TUKeyboardPickerViewDidSelected', (data) => { 44 | console.log(`TUKeyboardPickerViewDidSelected => data => ${data['selectedIndex']}`); 45 | var currentUid = data['currentUid']; 46 | var selectedIndex = data['selectedIndex']; 47 | let eventHandler = RCTKeyboardToolbarHelper.getCallback(currentUid).onPickerSelect; 48 | if (eventHandler) { 49 | eventHandler(selectedIndex); 50 | } 51 | }); 52 | 53 | NativeAppEventEmitter.addListener('TUKeyboardDatePickerViewDidSelected', (data) => { 54 | console.log(`TUKeyboardDatePickerViewDidSelected => data => ${data['selectedDate']}`); 55 | var currentUid = data['currentUid']; 56 | var selectedDate = data['selectedDate']; 57 | let eventHandler = RCTKeyboardToolbarHelper.getCallback(currentUid).onDateSelect; 58 | if (eventHandler) { 59 | eventHandler(selectedDate); 60 | } 61 | }); 62 | 63 | class RCTKeyboardToolbarManager { 64 | static configure(node, options, callbacks) { 65 | var reactNode = findNodeHandle(node); 66 | options.uid = RCTKeyboardToolbarHelper.getUid(); 67 | KeyboardToolbar.configure(reactNode, options, (error, currentUid) => { 68 | node.uid = currentUid; 69 | if (!error) { 70 | RCTKeyboardToolbarHelper.setCallback(currentUid, { 71 | onCancel: callbacks.onCancel, 72 | onDone: callbacks.onDone, 73 | onPickerSelect: callbacks.onPickerSelect, 74 | onDateSelect: callbacks.onDateSelect 75 | }); 76 | } 77 | }); 78 | } 79 | static dismissKeyboard(node) { 80 | // var nodeHandle = findNodeHandle(node); 81 | // KeyboardToolbar.dismissKeyboard(nodeHandle); 82 | Keyboard.dismiss(); 83 | } 84 | static moveCursorToLast(node) { 85 | var nodeHandle = findNodeHandle(node); 86 | KeyboardToolbar.moveCursorToLast(nodeHandle); 87 | } 88 | static setSelectedTextRange(node, NSRange) { 89 | var nodeHandle = findNodeHandle(node); 90 | KeyboardToolbar.setSelectedTextRange(nodeHandle, NSRange); 91 | } 92 | static setDate(node, NSDate) { 93 | var nodeHandle = findNodeHandle(node); 94 | KeyboardToolbar.setDate(nodeHandle, NSDate); 95 | } 96 | static setPickerRowByIndex(node, NSInteger) { 97 | var nodeHandle = findNodeHandle(node); 98 | KeyboardToolbar.setPickerRowByIndex(nodeHandle, NSInteger); 99 | } 100 | static reloadPickerData(node, NSArray) { 101 | var nodeHandle = findNodeHandle(node); 102 | KeyboardToolbar.reloadPickerData(nodeHandle, NSArray); 103 | } 104 | } 105 | 106 | class RCTKeyboardToolbarTextInput extends React.Component { 107 | componentDidMount() { 108 | var pickerViewData = []; 109 | if (this.props.pickerViewData) { 110 | this.props.pickerViewData.map((eachData) => { 111 | pickerViewData.push(eachData.label); 112 | }); 113 | } 114 | 115 | var callbacks = { 116 | onCancel: () => { 117 | // onCancel 118 | if (this.props.onCancel) { 119 | this.props.onCancel(RCTKeyboardToolbarManager.dismissKeyboard.bind(this, this.refs.input)); 120 | } 121 | }, 122 | onDone: () => { 123 | // onDone 124 | if (this.props.onDone) { 125 | this.props.onDone(RCTKeyboardToolbarManager.dismissKeyboard.bind(this, this.refs.input)); 126 | } 127 | }, 128 | onPickerSelect: this.props.onPickerSelect, 129 | onDateSelect: this.props.onDateSelect 130 | }; 131 | 132 | RCTKeyboardToolbarManager.configure(this.refs.input, { 133 | barStyle: this.props.barStyle, 134 | leftButtonText: this.props.leftButtonText, 135 | rightButtonText: this.props.rightButtonText, 136 | pickerViewData: pickerViewData, 137 | datePickerOptions: this.props.datePickerOptions, 138 | tintColor: processColor(this.props.tintColor) 139 | }, callbacks); 140 | } 141 | componentWillUnmount() { 142 | RCTKeyboardToolbarHelper.clearCallback(this.refs.input.uid); 143 | } 144 | dismissKeyboard() { 145 | RCTKeyboardToolbarManager.dismissKeyboard(this.refs.input); 146 | } 147 | moveCursorToLast() { 148 | RCTKeyboardToolbarManager.moveCursorToLast(this.refs.input); 149 | } 150 | setSelection(start, length) { 151 | RCTKeyboardToolbarManager.setSelectedTextRange(this.refs.input, { 152 | start: start, 153 | length: length 154 | }); 155 | } 156 | setDate(date) { 157 | RCTKeyboardToolbarManager.setDate(this.refs.input, { 158 | date: date 159 | }); 160 | } 161 | setPickerRowByIndex(index) { 162 | RCTKeyboardToolbarManager.setPickerRowByIndex(this.refs.input, { 163 | index: index 164 | }); 165 | } 166 | reloadPickerData(data) { 167 | data = data.map((item) => { 168 | return item.label; 169 | }); 170 | 171 | RCTKeyboardToolbarManager.reloadPickerData(this.refs.input, { 172 | data 173 | }); 174 | } 175 | focus() { 176 | this.refs.input.focus(); 177 | } 178 | clear() { 179 | this.refs.input.clear(); 180 | } 181 | render() { 182 | return (); 183 | } 184 | } 185 | 186 | module.exports = RCTKeyboardToolbarTextInput; 187 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-textinput-utils", 3 | "version": "0.3.7", 4 | "description": "A react native extension which allows you to control TextInput better.", 5 | "main": "index.ios.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/DickyT/react-native-textinput-utils.git" 9 | }, 10 | "keywords": [ 11 | "react-native", 12 | "react", 13 | "ios", 14 | "toolbar", 15 | "textinput" 16 | ], 17 | "author": "DickyT", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/DickyT/react-native-textinput-utils/issues" 21 | }, 22 | "homepage": "https://github.com/DickyT/react-native-textinput-utils#readme" 23 | } 24 | --------------------------------------------------------------------------------