├── .gitignore
├── README.md
├── android
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ ├── cn
│ └── reactnative
│ │ └── customkeyboard
│ │ └── RNCustomKeyboardPackage.java
│ └── com
│ └── facebook
│ └── react
│ └── uimanager
│ └── RNCustomKeyboardModule.java
├── index.js
├── ios
├── RNCustomKeyboard.h
├── RNCustomKeyboard.m
└── RNCustomKeyboard.xcodeproj
│ └── project.pbxproj
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | npm-debug*
3 | .idea
4 | node_modules
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # react-native-custom-keyboard
3 |
4 | ## Getting started
5 |
6 | `$ npm install react-native-custom-keyboard --save`
7 |
8 | ### Mostly automatic installation
9 |
10 | `$ react-native link react-native-custom-keyboard`
11 |
12 | ### Manual installation
13 |
14 |
15 | #### iOS
16 |
17 | 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
18 | 2. Go to `node_modules` ➜ `react-native-custom-keyboard` and add `RNCustomKeyboard.xcodeproj`
19 | 3. In XCode, in the project navigator, select your project. Add `libRNCustomKeyboard.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
20 | 4. Run your project (`Cmd+R`)<
21 |
22 | #### Android
23 |
24 | 1. Open up `android/app/src/main/java/[...]/MainActivity.java`
25 | - Add `import cn.reactnative.customkeyboard.RNCustomKeyboardPackage;` to the imports at the top of the file
26 | - Add `new RNCustomKeyboardPackage()` to the list returned by the `getPackages()` method
27 | 2. Append the following lines to `android/settings.gradle`:
28 | ```
29 | include ':react-native-custom-keyboard'
30 | project(':react-native-custom-keyboard').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-custom-keyboard/android')
31 | ```
32 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
33 | ```
34 | compile project(':react-native-custom-keyboard')
35 | ```
36 |
37 |
38 | ## Usage
39 |
40 | Register a component as custom keyboard:
41 |
42 | ```javascript
43 | import React, { Component } from 'react';
44 | import {
45 | TouchableOpacity,
46 | Text,
47 | View,
48 | } from 'react-native';
49 | import { register, insertText } from 'react-native-custom-keyboard';
50 |
51 | class MyKeyboard extends Component {
52 | onPress = () => {
53 | insertText(this.props.tag, 'Hello, world');
54 | };
55 | render() {
56 | return (
57 |
58 |
59 | Hello, world
60 |
61 |
62 | );
63 | }
64 | }
65 |
66 | register('hello', () => MyKeyboard);
67 | ```
68 |
69 | Use `CustomTextInput` instead of `TextInput`.
70 |
71 | ```javascript
72 | import React, { Component } from 'react';
73 | import {CustomTextInput} from 'react-native-custom-keyboard';
74 |
75 | class MyPage extends Component {
76 | state = {
77 | value: '';
78 | };
79 | onChangeText = text => {
80 | this.setState({value: text});
81 | };
82 | render() {
83 | return (
84 |
85 |
86 |
87 | );
88 | }
89 | }
90 | ```
91 |
92 | ## API
93 |
94 | ### register(type, type)
95 |
96 | Register a custom keyboard type.
97 |
98 | ### install(tag, type)
99 |
100 | Install custom keyboard to a `TextInput`.
101 |
102 | Generally you can use CustomTextInput instead of this. But you can use this API
103 | to install/change custom keyboard dynamically.
104 |
105 | ### uninstall(tag)
106 |
107 | Uninstall custom keyboard from a `TextInput` dynamically.
108 |
109 | ### insertText(tag, text)
110 |
111 | Use in a custom keyboard, insert text to `TextInput`.
112 |
113 | ### backSpace(tag)
114 |
115 | Use in a custom keyboard, delete selected text or the charactor before cursor.
116 |
117 | ### doDelete(tag)
118 |
119 | Use in a custom keyboard, delete selected text or the charactor after cursor.
120 |
121 | ### moveLeft(tag)
122 |
123 | Use in a custom keyboard, move cursor to selection start or move cursor left.
124 |
125 | ### moveRight(tag)
126 |
127 | Use in a custom keyboard, move cursor to selection end or move cursor right.
128 |
129 | ### switchSystemKeyboard(tag)
130 |
131 | Use in a custom keyboard. Switch to system keyboard.
132 |
133 | Next time user press or focus on the `TextInput`, custom keyboard will
134 | appear again. To keep using system keyboard, call `uninstall` instead.
135 |
136 | ### CustomTextInput
137 |
138 | Use instead of `TextInput`, this component support all properties of `TextInput`.
139 |
140 | #### prop: customKeyboardType: string
141 |
142 | Use a registered custom keyboard.
143 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | apply plugin: 'com.android.library'
3 |
4 | android {
5 | compileSdkVersion 23
6 | buildToolsVersion "23.0.1"
7 |
8 | defaultConfig {
9 | minSdkVersion 16
10 | targetSdkVersion 22
11 | versionCode 1
12 | versionName "1.0"
13 | ndk {
14 | abiFilters "armeabi-v7a", "x86"
15 | }
16 | }
17 | lintOptions {
18 | warning 'InvalidPackage'
19 | }
20 | }
21 |
22 | dependencies {
23 | compile 'com.facebook.react:react-native:+'
24 | }
25 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/src/main/java/cn/reactnative/customkeyboard/RNCustomKeyboardPackage.java:
--------------------------------------------------------------------------------
1 |
2 | package cn.reactnative.customkeyboard;
3 |
4 | import java.util.Arrays;
5 | import java.util.Collections;
6 | import java.util.List;
7 |
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.react.bridge.NativeModule;
10 | import com.facebook.react.bridge.ReactApplicationContext;
11 | import com.facebook.react.uimanager.RNCustomKeyboardModule;
12 | import com.facebook.react.uimanager.ViewManager;
13 | import com.facebook.react.bridge.JavaScriptModule;
14 | public class RNCustomKeyboardPackage implements ReactPackage {
15 | @Override
16 | public List createNativeModules(ReactApplicationContext reactContext) {
17 | return Arrays.asList(new RNCustomKeyboardModule(reactContext));
18 | }
19 |
20 | @Override
21 | public List> createJSModules() {
22 | return Collections.emptyList();
23 | }
24 |
25 | @Override
26 | public List createViewManagers(ReactApplicationContext reactContext) {
27 | return Collections.emptyList();
28 | }
29 | }
--------------------------------------------------------------------------------
/android/src/main/java/com/facebook/react/uimanager/RNCustomKeyboardModule.java:
--------------------------------------------------------------------------------
1 |
2 | package com.facebook.react.uimanager;
3 |
4 | import android.app.Activity;
5 | import android.graphics.Color;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.os.Looper;
9 | import android.util.Log;
10 | import android.view.MotionEvent;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.view.inputmethod.InputMethodManager;
14 | import android.widget.EditText;
15 | import android.widget.RelativeLayout;
16 |
17 | import com.facebook.react.ReactApplication;
18 | import com.facebook.react.ReactRootView;
19 | import com.facebook.react.bridge.Arguments;
20 | import com.facebook.react.bridge.LifecycleEventListener;
21 | import com.facebook.react.bridge.Promise;
22 | import com.facebook.react.bridge.ReactApplicationContext;
23 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
24 | import com.facebook.react.bridge.ReactMethod;
25 | import com.facebook.react.bridge.ReadableMap;
26 | import com.facebook.react.bridge.ReadableMapKeySetIterator;
27 | import com.facebook.react.bridge.UiThreadUtil;
28 | import com.facebook.react.bridge.WritableArray;
29 | import com.facebook.react.uimanager.RootView;
30 | import com.facebook.react.uimanager.UIManagerModule;
31 | import com.facebook.react.uimanager.UIViewOperationQueue;
32 | import com.facebook.react.views.textinput.ReactEditText;
33 |
34 | public class RNCustomKeyboardModule extends ReactContextBaseJavaModule {
35 | private final int TAG_ID = 0xdeadbeaf;
36 | private final ReactApplicationContext reactContext;
37 |
38 | public RNCustomKeyboardModule(ReactApplicationContext reactContext) {
39 | super(reactContext);
40 | this.reactContext = reactContext;
41 | }
42 |
43 | Handler handle = new Handler(Looper.getMainLooper());
44 |
45 | private ReactEditText getEditById(int id) {
46 | UIViewOperationQueue uii = this.getReactApplicationContext().getNativeModule(UIManagerModule.class).getUIImplementation().getUIViewOperationQueue();
47 | return (ReactEditText) uii.getNativeViewHierarchyManager().resolveView(id);
48 | }
49 |
50 | @ReactMethod
51 | public void install(final int tag, final String type) {
52 | UiThreadUtil.runOnUiThread(new Runnable() {
53 | @Override
54 | public void run() {
55 | final Activity activity = getCurrentActivity();
56 | final ReactEditText edit = getEditById(tag);
57 | if (edit == null) {
58 | return;
59 | }
60 |
61 | edit.setTag(TAG_ID, createCustomKeyboard(activity, tag, type));
62 |
63 | edit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
64 | @Override
65 | public void onFocusChange(final View v, boolean hasFocus) {
66 | if (hasFocus) {
67 | View keyboard = (View)edit.getTag(TAG_ID);
68 | if (keyboard.getParent() == null) {
69 | activity.addContentView(keyboard, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
70 | }
71 | UiThreadUtil.runOnUiThread(new Runnable() {
72 | @Override
73 | public void run() {
74 | ((InputMethodManager) getReactApplicationContext().getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
75 | }
76 | });
77 | } else {
78 | View keyboard = (View)edit.getTag(TAG_ID);
79 | if (keyboard.getParent() != null) {
80 | ((ViewGroup) keyboard.getParent()).removeView(keyboard);
81 | }
82 | }
83 | }
84 | });
85 |
86 | edit.setOnClickListener(new View.OnClickListener(){
87 | @Override
88 | public void onClick(final View v) {
89 | View keyboard = (View)edit.getTag(TAG_ID);
90 | if (keyboard.getParent() == null) {
91 | activity.addContentView(keyboard, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
92 | }
93 | UiThreadUtil.runOnUiThread(new Runnable() {
94 | @Override
95 | public void run() {
96 | ((InputMethodManager) getReactApplicationContext().getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
97 | }
98 | });
99 | }
100 | });
101 | }
102 | });
103 | }
104 |
105 | ReactRootView rootView = null;
106 |
107 | private View createCustomKeyboard(Activity activity, int tag, String type) {
108 | RelativeLayout layout = new RelativeLayout(activity);
109 | rootView = new ReactRootView(this.getReactApplicationContext());
110 | rootView.setBackgroundColor(Color.WHITE);
111 |
112 | Bundle bundle = new Bundle();
113 | bundle.putInt("tag", tag);
114 | bundle.putString("type", type);
115 | rootView.startReactApplication(
116 | ((ReactApplication) activity.getApplication()).getReactNativeHost().getReactInstanceManager(),
117 | "CustomKeyboard",
118 | bundle);
119 |
120 | final float scale = activity.getResources().getDisplayMetrics().density;
121 | RelativeLayout.LayoutParams lParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Math.round(216*scale));
122 | lParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
123 | layout.addView(rootView, lParams);
124 | // activity.addContentView(layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
125 | return layout;
126 | }
127 |
128 | @ReactMethod
129 | public void uninstall(final int tag) {
130 | UiThreadUtil.runOnUiThread(new Runnable() {
131 | @Override
132 | public void run() {
133 | final Activity activity = getCurrentActivity();
134 | final ReactEditText edit = getEditById(tag);
135 | if (edit == null) {
136 | return;
137 | }
138 |
139 | edit.setTag(TAG_ID, null);
140 | }
141 | });
142 | }
143 |
144 | @ReactMethod
145 | public void insertText(final int tag, final String text) {
146 | UiThreadUtil.runOnUiThread(new Runnable() {
147 | @Override
148 | public void run() {
149 | final Activity activity = getCurrentActivity();
150 | final ReactEditText edit = getEditById(tag);
151 | if (edit == null) {
152 | return;
153 | }
154 |
155 | int start = Math.max(edit.getSelectionStart(), 0);
156 | int end = Math.max(edit.getSelectionEnd(), 0);
157 | edit.getText().replace(Math.min(start, end), Math.max(start, end),
158 | text, 0, text.length());
159 | }
160 | });
161 | }
162 |
163 | @ReactMethod
164 | public void backSpace(final int tag) {
165 | UiThreadUtil.runOnUiThread(new Runnable() {
166 | @Override
167 | public void run() {
168 | final Activity activity = getCurrentActivity();
169 | final ReactEditText edit = getEditById(tag);
170 | if (edit == null) {
171 | return;
172 | }
173 |
174 | int start = Math.max(edit.getSelectionStart(), 0);
175 | int end = Math.max(edit.getSelectionEnd(), 0);
176 | if (start != end) {
177 | edit.getText().delete(start, end);
178 | } else if (start > 0){
179 | edit.getText().delete(start - 1, end);
180 | }
181 | }
182 | });
183 | }
184 |
185 | @ReactMethod
186 | public void doDelete(final int tag) {
187 | UiThreadUtil.runOnUiThread(new Runnable() {
188 | @Override
189 | public void run() {
190 | final Activity activity = getCurrentActivity();
191 | final ReactEditText edit = getEditById(tag);
192 | if (edit == null) {
193 | return;
194 | }
195 |
196 | int start = Math.max(edit.getSelectionStart(), 0);
197 | int end = Math.max(edit.getSelectionEnd(), 0);
198 | if (start != end) {
199 | edit.getText().delete(start, end);
200 | } else if (start > 0){
201 | edit.getText().delete(start, end+1);
202 | }
203 | }
204 | });
205 | }
206 |
207 | @ReactMethod
208 | public void moveLeft(final int tag) {
209 | UiThreadUtil.runOnUiThread(new Runnable() {
210 | @Override
211 | public void run() {
212 | final Activity activity = getCurrentActivity();
213 | final ReactEditText edit = getEditById(tag);
214 | if (edit == null) {
215 | return;
216 | }
217 |
218 | int start = Math.max(edit.getSelectionStart(), 0);
219 | int end = Math.max(edit.getSelectionEnd(), 0);
220 | if (start != end) {
221 | edit.setSelection(start, start);
222 | } else {
223 | edit.setSelection(start - 1, start - 1);
224 | }
225 | }
226 | });
227 | }
228 |
229 | @ReactMethod
230 | public void moveRight(final int tag) {
231 | UiThreadUtil.runOnUiThread(new Runnable() {
232 | @Override
233 | public void run() {
234 | final Activity activity = getCurrentActivity();
235 | final ReactEditText edit = getEditById(tag);
236 | if (edit == null) {
237 | return;
238 | }
239 |
240 | int start = Math.max(edit.getSelectionStart(), 0);
241 | int end = Math.max(edit.getSelectionEnd(), 0);
242 | if (start != end) {
243 | edit.setSelection(end, end);
244 | } else if (start > 0){
245 | edit.setSelection(end + 1, end + 1);
246 | }
247 | }
248 | });
249 | }
250 |
251 | @ReactMethod
252 | public void switchSystemKeyboard(final int tag) {
253 | UiThreadUtil.runOnUiThread(new Runnable() {
254 | @Override
255 | public void run() {
256 | final Activity activity = getCurrentActivity();
257 | final ReactEditText edit = getEditById(tag);
258 | if (edit == null) {
259 | return;
260 | }
261 |
262 | View keyboard = (View)edit.getTag(TAG_ID);
263 | if (keyboard.getParent() != null) {
264 | ((ViewGroup) keyboard.getParent()).removeView(keyboard);
265 | }
266 | UiThreadUtil.runOnUiThread(new Runnable() {
267 |
268 | @Override
269 | public void run() {
270 | ((InputMethodManager) getReactApplicationContext().getSystemService(Activity.INPUT_METHOD_SERVICE)).showSoftInput(edit, InputMethodManager.SHOW_IMPLICIT);
271 | }
272 | });
273 | }
274 | });
275 | }
276 |
277 | @Override
278 | public String getName() {
279 | return "CustomKeyboard";
280 | }
281 | }
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 |
2 | import React, { Component, PropTypes } from 'react';
3 |
4 | import {
5 | NativeModules,
6 | TextInput,
7 | findNodeHandle,
8 | AppRegistry,
9 | } from 'react-native';
10 |
11 | const { CustomKeyboard} = NativeModules;
12 |
13 | const {
14 | install, uninstall,
15 | insertText, backSpace, doDelete,
16 | moveLeft, moveRight,
17 | switchSystemKeyboard,
18 | } = CustomKeyboard;
19 |
20 | export {
21 | install, uninstall,
22 | insertText, backSpace, doDelete,
23 | moveLeft, moveRight,
24 | switchSystemKeyboard,
25 | };
26 |
27 | const keyboardTypeRegistry = {};
28 |
29 | export function register(type, factory) {
30 | keyboardTypeRegistry[type] = factory;
31 | }
32 |
33 | class CustomKeyboardContainer extends Component {
34 | render() {
35 | const {tag, type} = this.props;
36 | const factory = keyboardTypeRegistry[type];
37 | if (!factory) {
38 | console.warn(`Custom keyboard type ${type} not registered.`);
39 | return null;
40 | }
41 | const Comp = factory();
42 | return ;
43 | }
44 | }
45 |
46 | AppRegistry.registerComponent("CustomKeyboard", ()=>CustomKeyboardContainer);
47 |
48 | export class CustomTextInput extends Component {
49 | static propTypes = {
50 | ...TextInput.propTypes,
51 | customKeyboardType: PropTypes.string,
52 | };
53 | componentDidMount() {
54 | install(findNodeHandle(this.input), this.props.customKeyboardType);
55 | }
56 | componentWillReceiveProps(newProps) {
57 | if (newProps.customKeyboardType !== this.props.customKeyboardType) {
58 | install(findNodeHandle(this.input), newProps.customKeyboardType);
59 | }
60 | }
61 | onRef = ref => {
62 | this.input = ref;
63 | };
64 | render() {
65 | const { customKeyboardType, ...others } = this.props;
66 | return ;
67 | }
68 | }
--------------------------------------------------------------------------------
/ios/RNCustomKeyboard.h:
--------------------------------------------------------------------------------
1 |
2 | #import "RCTBridgeModule.h"
3 |
4 | @interface RNCustomKeyboard : NSObject
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/RNCustomKeyboard.m:
--------------------------------------------------------------------------------
1 |
2 | #import "RNCustomKeyboard.h"
3 | #import "RCTBridge+Private.h"
4 | #import "RCTUIManager.h"
5 |
6 | @implementation RNCustomKeyboard
7 |
8 | @synthesize bridge = _bridge;
9 |
10 | - (dispatch_queue_t)methodQueue
11 | {
12 | return dispatch_get_main_queue();
13 | }
14 | RCT_EXPORT_MODULE(CustomKeyboard)
15 |
16 | RCT_EXPORT_METHOD(install:(nonnull NSNumber *)reactTag withType:(nonnull NSString *)keyboardType)
17 | {
18 | UIView* inputView = [[RCTRootView alloc] initWithBridge:((RCTBatchedBridge *)_bridge).parentBridge moduleName:@"CustomKeyboard" initialProperties:
19 | @{
20 | @"tag": reactTag,
21 | @"type": keyboardType
22 | }
23 | ];
24 |
25 | UITextView *view = (UITextView*)[_bridge.uiManager viewForReactTag:reactTag];
26 |
27 | view.inputView = inputView;
28 | [view reloadInputViews];
29 | }
30 |
31 | RCT_EXPORT_METHOD(uninstall:(nonnull NSNumber *)reactTag)
32 | {
33 | UITextView *view = (UITextView*)[_bridge.uiManager viewForReactTag:reactTag];
34 |
35 | view.inputView = nil;
36 | [view reloadInputViews];
37 | }
38 |
39 | RCT_EXPORT_METHOD(insertText:(nonnull NSNumber *)reactTag withText:(NSString*)text) {
40 | UITextView *view = (UITextView*)[_bridge.uiManager viewForReactTag:reactTag];
41 |
42 | [view replaceRange:view.selectedTextRange withText:text];
43 | }
44 |
45 | RCT_EXPORT_METHOD(backSpace:(nonnull NSNumber *)reactTag) {
46 | UITextView *view = (UITextView*)[_bridge.uiManager viewForReactTag:reactTag];
47 |
48 | UITextRange* range = view.selectedTextRange;
49 | if ([view comparePosition:range.start toPosition:range.end] == 0) {
50 | range = [view textRangeFromPosition:[view positionFromPosition:range.start offset:-1] toPosition:range.start];
51 | }
52 | [view replaceRange:range withText:@""];
53 | }
54 |
55 | RCT_EXPORT_METHOD(doDelete:(nonnull NSNumber *)reactTag) {
56 | UITextView *view = (UITextView*)[_bridge.uiManager viewForReactTag:reactTag];
57 |
58 | UITextRange* range = view.selectedTextRange;
59 | if ([view comparePosition:range.start toPosition:range.end] == 0) {
60 | range = [view textRangeFromPosition:range.start toPosition:[view positionFromPosition: range.start offset: 1]];
61 | }
62 | [view replaceRange:range withText:@""];
63 | }
64 |
65 | RCT_EXPORT_METHOD(moveLeft:(nonnull NSNumber *)reactTag) {
66 | UITextView *view = (UITextView*)[_bridge.uiManager viewForReactTag:reactTag];
67 |
68 | UITextRange* range = view.selectedTextRange;
69 | UITextPosition* position = range.start;
70 |
71 | if ([view comparePosition:range.start toPosition:range.end] == 0) {
72 | position = [view positionFromPosition: position, offset: -1];
73 | }
74 |
75 | view.selectedTextRange = [view textRangeFromPosition: position toPosition:position];
76 | }
77 |
78 | RCT_EXPORT_METHOD(moveRight:(nonnull NSNumber *)reactTag) {
79 | UITextView *view = (UITextView*)[_bridge.uiManager viewForReactTag:reactTag];
80 |
81 | UITextRange* range = view.selectedTextRange;
82 | UITextPosition* position = range.end;
83 |
84 | if ([view comparePosition:range.start toPosition:range.end] == 0) {
85 | position = [view positionFromPosition: position, offset: 1];
86 | }
87 |
88 | view.selectedTextRange = [view textRangeFromPosition: position toPosition:position];
89 | }
90 |
91 | RCT_EXPORT_METHOD(switchSystemKeyboard:(nonnull NSNumber*) reactTag) {
92 | UITextView *view = [_bridge.uiManager viewForReactTag:reactTag];
93 | UIView* inputView = view.inputView;
94 | view.inputView = nil;
95 | [view reloadInputViews];
96 | view.inputView = inputView;
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/ios/RNCustomKeyboard.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B3E7B58A1CC2AC0600A0062D /* RNCustomKeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNCustomKeyboard.m */; };
11 | /* End PBXBuildFile section */
12 |
13 | /* Begin PBXCopyFilesBuildPhase section */
14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = {
15 | isa = PBXCopyFilesBuildPhase;
16 | buildActionMask = 2147483647;
17 | dstPath = "include/$(PRODUCT_NAME)";
18 | dstSubfolderSpec = 16;
19 | files = (
20 | );
21 | runOnlyForDeploymentPostprocessing = 0;
22 | };
23 | /* End PBXCopyFilesBuildPhase section */
24 |
25 | /* Begin PBXFileReference section */
26 | 134814201AA4EA6300B7C361 /* libRNCustomKeyboard.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCustomKeyboard.a; sourceTree = BUILT_PRODUCTS_DIR; };
27 | B3E7B5881CC2AC0600A0062D /* RNCustomKeyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCustomKeyboard.h; sourceTree = ""; };
28 | B3E7B5891CC2AC0600A0062D /* RNCustomKeyboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCustomKeyboard.m; sourceTree = ""; };
29 | /* End PBXFileReference section */
30 |
31 | /* Begin PBXFrameworksBuildPhase section */
32 | 58B511D81A9E6C8500147676 /* Frameworks */ = {
33 | isa = PBXFrameworksBuildPhase;
34 | buildActionMask = 2147483647;
35 | files = (
36 | );
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXFrameworksBuildPhase section */
40 |
41 | /* Begin PBXGroup section */
42 | 134814211AA4EA7D00B7C361 /* Products */ = {
43 | isa = PBXGroup;
44 | children = (
45 | 134814201AA4EA6300B7C361 /* libRNCustomKeyboard.a */,
46 | );
47 | name = Products;
48 | sourceTree = "";
49 | };
50 | 58B511D21A9E6C8500147676 = {
51 | isa = PBXGroup;
52 | children = (
53 | B3E7B5881CC2AC0600A0062D /* RNCustomKeyboard.h */,
54 | B3E7B5891CC2AC0600A0062D /* RNCustomKeyboard.m */,
55 | 134814211AA4EA7D00B7C361 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | /* End PBXGroup section */
60 |
61 | /* Begin PBXNativeTarget section */
62 | 58B511DA1A9E6C8500147676 /* RNCustomKeyboard */ = {
63 | isa = PBXNativeTarget;
64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCustomKeyboard" */;
65 | buildPhases = (
66 | 58B511D71A9E6C8500147676 /* Sources */,
67 | 58B511D81A9E6C8500147676 /* Frameworks */,
68 | 58B511D91A9E6C8500147676 /* CopyFiles */,
69 | );
70 | buildRules = (
71 | );
72 | dependencies = (
73 | );
74 | name = RNCustomKeyboard;
75 | productName = RCTDataManager;
76 | productReference = 134814201AA4EA6300B7C361 /* libRNCustomKeyboard.a */;
77 | productType = "com.apple.product-type.library.static";
78 | };
79 | /* End PBXNativeTarget section */
80 |
81 | /* Begin PBXProject section */
82 | 58B511D31A9E6C8500147676 /* Project object */ = {
83 | isa = PBXProject;
84 | attributes = {
85 | LastUpgradeCheck = 0610;
86 | ORGANIZATIONNAME = Facebook;
87 | TargetAttributes = {
88 | 58B511DA1A9E6C8500147676 = {
89 | CreatedOnToolsVersion = 6.1.1;
90 | };
91 | };
92 | };
93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCustomKeyboard" */;
94 | compatibilityVersion = "Xcode 3.2";
95 | developmentRegion = English;
96 | hasScannedForEncodings = 0;
97 | knownRegions = (
98 | en,
99 | );
100 | mainGroup = 58B511D21A9E6C8500147676;
101 | productRefGroup = 58B511D21A9E6C8500147676;
102 | projectDirPath = "";
103 | projectRoot = "";
104 | targets = (
105 | 58B511DA1A9E6C8500147676 /* RNCustomKeyboard */,
106 | );
107 | };
108 | /* End PBXProject section */
109 |
110 | /* Begin PBXSourcesBuildPhase section */
111 | 58B511D71A9E6C8500147676 /* Sources */ = {
112 | isa = PBXSourcesBuildPhase;
113 | buildActionMask = 2147483647;
114 | files = (
115 | B3E7B58A1CC2AC0600A0062D /* RNCustomKeyboard.m in Sources */,
116 | );
117 | runOnlyForDeploymentPostprocessing = 0;
118 | };
119 | /* End PBXSourcesBuildPhase section */
120 |
121 | /* Begin XCBuildConfiguration section */
122 | 58B511ED1A9E6C8500147676 /* Debug */ = {
123 | isa = XCBuildConfiguration;
124 | buildSettings = {
125 | ALWAYS_SEARCH_USER_PATHS = NO;
126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
127 | CLANG_CXX_LIBRARY = "libc++";
128 | CLANG_ENABLE_MODULES = YES;
129 | CLANG_ENABLE_OBJC_ARC = YES;
130 | CLANG_WARN_BOOL_CONVERSION = YES;
131 | CLANG_WARN_CONSTANT_CONVERSION = YES;
132 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
133 | CLANG_WARN_EMPTY_BODY = YES;
134 | CLANG_WARN_ENUM_CONVERSION = YES;
135 | CLANG_WARN_INT_CONVERSION = YES;
136 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
137 | CLANG_WARN_UNREACHABLE_CODE = YES;
138 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
139 | COPY_PHASE_STRIP = NO;
140 | ENABLE_STRICT_OBJC_MSGSEND = YES;
141 | GCC_C_LANGUAGE_STANDARD = gnu99;
142 | GCC_DYNAMIC_NO_PIC = NO;
143 | GCC_OPTIMIZATION_LEVEL = 0;
144 | GCC_PREPROCESSOR_DEFINITIONS = (
145 | "DEBUG=1",
146 | "$(inherited)",
147 | );
148 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
149 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
150 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
151 | GCC_WARN_UNDECLARED_SELECTOR = YES;
152 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
153 | GCC_WARN_UNUSED_FUNCTION = YES;
154 | GCC_WARN_UNUSED_VARIABLE = YES;
155 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
156 | MTL_ENABLE_DEBUG_INFO = YES;
157 | ONLY_ACTIVE_ARCH = YES;
158 | SDKROOT = iphoneos;
159 | };
160 | name = Debug;
161 | };
162 | 58B511EE1A9E6C8500147676 /* Release */ = {
163 | isa = XCBuildConfiguration;
164 | buildSettings = {
165 | ALWAYS_SEARCH_USER_PATHS = NO;
166 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
167 | CLANG_CXX_LIBRARY = "libc++";
168 | CLANG_ENABLE_MODULES = YES;
169 | CLANG_ENABLE_OBJC_ARC = YES;
170 | CLANG_WARN_BOOL_CONVERSION = YES;
171 | CLANG_WARN_CONSTANT_CONVERSION = YES;
172 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
173 | CLANG_WARN_EMPTY_BODY = YES;
174 | CLANG_WARN_ENUM_CONVERSION = YES;
175 | CLANG_WARN_INT_CONVERSION = YES;
176 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
177 | CLANG_WARN_UNREACHABLE_CODE = YES;
178 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
179 | COPY_PHASE_STRIP = YES;
180 | ENABLE_NS_ASSERTIONS = NO;
181 | ENABLE_STRICT_OBJC_MSGSEND = YES;
182 | GCC_C_LANGUAGE_STANDARD = gnu99;
183 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
184 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
185 | GCC_WARN_UNDECLARED_SELECTOR = YES;
186 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
187 | GCC_WARN_UNUSED_FUNCTION = YES;
188 | GCC_WARN_UNUSED_VARIABLE = YES;
189 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
190 | MTL_ENABLE_DEBUG_INFO = NO;
191 | SDKROOT = iphoneos;
192 | VALIDATE_PRODUCT = YES;
193 | };
194 | name = Release;
195 | };
196 | 58B511F01A9E6C8500147676 /* Debug */ = {
197 | isa = XCBuildConfiguration;
198 | buildSettings = {
199 | HEADER_SEARCH_PATHS = (
200 | "$(inherited)",
201 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
202 | "$(SRCROOT)/../../../React/**",
203 | "$(SRCROOT)/../../react-native/React/**",
204 | );
205 | LIBRARY_SEARCH_PATHS = "$(inherited)";
206 | OTHER_LDFLAGS = "-ObjC";
207 | PRODUCT_NAME = RNCustomKeyboard;
208 | SKIP_INSTALL = YES;
209 | };
210 | name = Debug;
211 | };
212 | 58B511F11A9E6C8500147676 /* Release */ = {
213 | isa = XCBuildConfiguration;
214 | buildSettings = {
215 | HEADER_SEARCH_PATHS = (
216 | "$(inherited)",
217 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
218 | "$(SRCROOT)/../../../React/**",
219 | "$(SRCROOT)/../../react-native/React/**",
220 | );
221 | LIBRARY_SEARCH_PATHS = "$(inherited)";
222 | OTHER_LDFLAGS = "-ObjC";
223 | PRODUCT_NAME = RNCustomKeyboard;
224 | SKIP_INSTALL = YES;
225 | };
226 | name = Release;
227 | };
228 | /* End XCBuildConfiguration section */
229 |
230 | /* Begin XCConfigurationList section */
231 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNCustomKeyboard" */ = {
232 | isa = XCConfigurationList;
233 | buildConfigurations = (
234 | 58B511ED1A9E6C8500147676 /* Debug */,
235 | 58B511EE1A9E6C8500147676 /* Release */,
236 | );
237 | defaultConfigurationIsVisible = 0;
238 | defaultConfigurationName = Release;
239 | };
240 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNCustomKeyboard" */ = {
241 | isa = XCConfigurationList;
242 | buildConfigurations = (
243 | 58B511F01A9E6C8500147676 /* Debug */,
244 | 58B511F11A9E6C8500147676 /* Release */,
245 | );
246 | defaultConfigurationIsVisible = 0;
247 | defaultConfigurationName = Release;
248 | };
249 | /* End XCConfigurationList section */
250 | };
251 | rootObject = 58B511D31A9E6C8500147676 /* Project object */;
252 | }
253 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "name": "react-native-custom-keyboard",
4 | "version": "1.0.3",
5 | "description": "",
6 | "main": "index.js",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/reactnativecn/react-native-custom-keyboard.git"
13 | },
14 | "keywords": [
15 | "react-native"
16 | ],
17 | "author": "",
18 | "license": "",
19 | "peerDependencies": {
20 | "react-native": "^0.29.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------