├── .DS_Store
├── README.md
├── TestInputNumber.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── longpei.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── longpei.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── TestInputNumber.xcscheme
│ └── xcschememanagement.plist
├── TestInputNumber
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── CustomTextField.h
├── CustomTextField.m
├── Info.plist
├── ViewController.h
├── ViewController.m
└── main.m
├── TestInputNumberTests
├── Info.plist
└── TestInputNumberTests.m
├── TestInputNumberUITests
├── Info.plist
└── TestInputNumberUITests.m
└── imageFile.png
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coolll/SeparateTextField/b1962458dc7c55f822887382d5f2a88274b52fea/.DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SeparateTextField
2 |
3 | 2行代码就能实现以下效果:
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 分隔用户输入的字符串。适用于输入银行卡号、身份证号、手机号等场景。
13 | 支持固定数字分隔,如:
14 |
15 | 1111 2222 3333 4444 5555
16 |
17 | 支持自定义分隔,如:
18 | 136 6666 6666
19 |
20 | 可设置最多输入字符,这里设置的是实际输入字符,不计算分隔的空格。
21 | 可获取输入的实际内容。
22 |
23 | 此控件的构建流程请参考:[这里](http://www.jianshu.com/p/582cee0680b0)
24 |
25 |
26 |
--------------------------------------------------------------------------------
/TestInputNumber.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 07AFD4DB1ECAD4D10015BBFA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 07AFD4DA1ECAD4D10015BBFA /* main.m */; };
11 | 07AFD4DE1ECAD4D10015BBFA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 07AFD4DD1ECAD4D10015BBFA /* AppDelegate.m */; };
12 | 07AFD4E11ECAD4D10015BBFA /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 07AFD4E01ECAD4D10015BBFA /* ViewController.m */; };
13 | 07AFD4E41ECAD4D10015BBFA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07AFD4E21ECAD4D10015BBFA /* Main.storyboard */; };
14 | 07AFD4E61ECAD4D10015BBFA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07AFD4E51ECAD4D10015BBFA /* Assets.xcassets */; };
15 | 07AFD4E91ECAD4D10015BBFA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 07AFD4E71ECAD4D10015BBFA /* LaunchScreen.storyboard */; };
16 | 07AFD4F41ECAD4D10015BBFA /* TestInputNumberTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 07AFD4F31ECAD4D10015BBFA /* TestInputNumberTests.m */; };
17 | 07AFD4FF1ECAD4D10015BBFA /* TestInputNumberUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 07AFD4FE1ECAD4D10015BBFA /* TestInputNumberUITests.m */; };
18 | 07AFD50E1ECAD5500015BBFA /* CustomTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 07AFD50D1ECAD5500015BBFA /* CustomTextField.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | 07AFD4F01ECAD4D10015BBFA /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = 07AFD4CE1ECAD4D10015BBFA /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = 07AFD4D51ECAD4D10015BBFA;
27 | remoteInfo = TestInputNumber;
28 | };
29 | 07AFD4FB1ECAD4D10015BBFA /* PBXContainerItemProxy */ = {
30 | isa = PBXContainerItemProxy;
31 | containerPortal = 07AFD4CE1ECAD4D10015BBFA /* Project object */;
32 | proxyType = 1;
33 | remoteGlobalIDString = 07AFD4D51ECAD4D10015BBFA;
34 | remoteInfo = TestInputNumber;
35 | };
36 | /* End PBXContainerItemProxy section */
37 |
38 | /* Begin PBXFileReference section */
39 | 07AFD4D61ECAD4D10015BBFA /* TestInputNumber.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestInputNumber.app; sourceTree = BUILT_PRODUCTS_DIR; };
40 | 07AFD4DA1ECAD4D10015BBFA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
41 | 07AFD4DC1ECAD4D10015BBFA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
42 | 07AFD4DD1ECAD4D10015BBFA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
43 | 07AFD4DF1ECAD4D10015BBFA /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
44 | 07AFD4E01ECAD4D10015BBFA /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
45 | 07AFD4E31ECAD4D10015BBFA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
46 | 07AFD4E51ECAD4D10015BBFA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
47 | 07AFD4E81ECAD4D10015BBFA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
48 | 07AFD4EA1ECAD4D10015BBFA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
49 | 07AFD4EF1ECAD4D10015BBFA /* TestInputNumberTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestInputNumberTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
50 | 07AFD4F31ECAD4D10015BBFA /* TestInputNumberTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestInputNumberTests.m; sourceTree = ""; };
51 | 07AFD4F51ECAD4D10015BBFA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
52 | 07AFD4FA1ECAD4D10015BBFA /* TestInputNumberUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestInputNumberUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
53 | 07AFD4FE1ECAD4D10015BBFA /* TestInputNumberUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestInputNumberUITests.m; sourceTree = ""; };
54 | 07AFD5001ECAD4D10015BBFA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
55 | 07AFD50C1ECAD5500015BBFA /* CustomTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomTextField.h; sourceTree = ""; };
56 | 07AFD50D1ECAD5500015BBFA /* CustomTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomTextField.m; sourceTree = ""; };
57 | /* End PBXFileReference section */
58 |
59 | /* Begin PBXFrameworksBuildPhase section */
60 | 07AFD4D31ECAD4D10015BBFA /* Frameworks */ = {
61 | isa = PBXFrameworksBuildPhase;
62 | buildActionMask = 2147483647;
63 | files = (
64 | );
65 | runOnlyForDeploymentPostprocessing = 0;
66 | };
67 | 07AFD4EC1ECAD4D10015BBFA /* Frameworks */ = {
68 | isa = PBXFrameworksBuildPhase;
69 | buildActionMask = 2147483647;
70 | files = (
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | 07AFD4F71ECAD4D10015BBFA /* Frameworks */ = {
75 | isa = PBXFrameworksBuildPhase;
76 | buildActionMask = 2147483647;
77 | files = (
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | /* End PBXFrameworksBuildPhase section */
82 |
83 | /* Begin PBXGroup section */
84 | 07AFD4CD1ECAD4D10015BBFA = {
85 | isa = PBXGroup;
86 | children = (
87 | 07AFD4D81ECAD4D10015BBFA /* TestInputNumber */,
88 | 07AFD4F21ECAD4D10015BBFA /* TestInputNumberTests */,
89 | 07AFD4FD1ECAD4D10015BBFA /* TestInputNumberUITests */,
90 | 07AFD4D71ECAD4D10015BBFA /* Products */,
91 | );
92 | sourceTree = "";
93 | };
94 | 07AFD4D71ECAD4D10015BBFA /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 07AFD4D61ECAD4D10015BBFA /* TestInputNumber.app */,
98 | 07AFD4EF1ECAD4D10015BBFA /* TestInputNumberTests.xctest */,
99 | 07AFD4FA1ECAD4D10015BBFA /* TestInputNumberUITests.xctest */,
100 | );
101 | name = Products;
102 | sourceTree = "";
103 | };
104 | 07AFD4D81ECAD4D10015BBFA /* TestInputNumber */ = {
105 | isa = PBXGroup;
106 | children = (
107 | 07AFD4DC1ECAD4D10015BBFA /* AppDelegate.h */,
108 | 07AFD4DD1ECAD4D10015BBFA /* AppDelegate.m */,
109 | 07AFD4DF1ECAD4D10015BBFA /* ViewController.h */,
110 | 07AFD4E01ECAD4D10015BBFA /* ViewController.m */,
111 | 07AFD4E21ECAD4D10015BBFA /* Main.storyboard */,
112 | 07AFD4E51ECAD4D10015BBFA /* Assets.xcassets */,
113 | 07AFD4E71ECAD4D10015BBFA /* LaunchScreen.storyboard */,
114 | 07AFD4EA1ECAD4D10015BBFA /* Info.plist */,
115 | 07AFD4D91ECAD4D10015BBFA /* Supporting Files */,
116 | 07AFD50C1ECAD5500015BBFA /* CustomTextField.h */,
117 | 07AFD50D1ECAD5500015BBFA /* CustomTextField.m */,
118 | );
119 | path = TestInputNumber;
120 | sourceTree = "";
121 | };
122 | 07AFD4D91ECAD4D10015BBFA /* Supporting Files */ = {
123 | isa = PBXGroup;
124 | children = (
125 | 07AFD4DA1ECAD4D10015BBFA /* main.m */,
126 | );
127 | name = "Supporting Files";
128 | sourceTree = "";
129 | };
130 | 07AFD4F21ECAD4D10015BBFA /* TestInputNumberTests */ = {
131 | isa = PBXGroup;
132 | children = (
133 | 07AFD4F31ECAD4D10015BBFA /* TestInputNumberTests.m */,
134 | 07AFD4F51ECAD4D10015BBFA /* Info.plist */,
135 | );
136 | path = TestInputNumberTests;
137 | sourceTree = "";
138 | };
139 | 07AFD4FD1ECAD4D10015BBFA /* TestInputNumberUITests */ = {
140 | isa = PBXGroup;
141 | children = (
142 | 07AFD4FE1ECAD4D10015BBFA /* TestInputNumberUITests.m */,
143 | 07AFD5001ECAD4D10015BBFA /* Info.plist */,
144 | );
145 | path = TestInputNumberUITests;
146 | sourceTree = "";
147 | };
148 | /* End PBXGroup section */
149 |
150 | /* Begin PBXNativeTarget section */
151 | 07AFD4D51ECAD4D10015BBFA /* TestInputNumber */ = {
152 | isa = PBXNativeTarget;
153 | buildConfigurationList = 07AFD5031ECAD4D10015BBFA /* Build configuration list for PBXNativeTarget "TestInputNumber" */;
154 | buildPhases = (
155 | 07AFD4D21ECAD4D10015BBFA /* Sources */,
156 | 07AFD4D31ECAD4D10015BBFA /* Frameworks */,
157 | 07AFD4D41ECAD4D10015BBFA /* Resources */,
158 | );
159 | buildRules = (
160 | );
161 | dependencies = (
162 | );
163 | name = TestInputNumber;
164 | productName = TestInputNumber;
165 | productReference = 07AFD4D61ECAD4D10015BBFA /* TestInputNumber.app */;
166 | productType = "com.apple.product-type.application";
167 | };
168 | 07AFD4EE1ECAD4D10015BBFA /* TestInputNumberTests */ = {
169 | isa = PBXNativeTarget;
170 | buildConfigurationList = 07AFD5061ECAD4D10015BBFA /* Build configuration list for PBXNativeTarget "TestInputNumberTests" */;
171 | buildPhases = (
172 | 07AFD4EB1ECAD4D10015BBFA /* Sources */,
173 | 07AFD4EC1ECAD4D10015BBFA /* Frameworks */,
174 | 07AFD4ED1ECAD4D10015BBFA /* Resources */,
175 | );
176 | buildRules = (
177 | );
178 | dependencies = (
179 | 07AFD4F11ECAD4D10015BBFA /* PBXTargetDependency */,
180 | );
181 | name = TestInputNumberTests;
182 | productName = TestInputNumberTests;
183 | productReference = 07AFD4EF1ECAD4D10015BBFA /* TestInputNumberTests.xctest */;
184 | productType = "com.apple.product-type.bundle.unit-test";
185 | };
186 | 07AFD4F91ECAD4D10015BBFA /* TestInputNumberUITests */ = {
187 | isa = PBXNativeTarget;
188 | buildConfigurationList = 07AFD5091ECAD4D10015BBFA /* Build configuration list for PBXNativeTarget "TestInputNumberUITests" */;
189 | buildPhases = (
190 | 07AFD4F61ECAD4D10015BBFA /* Sources */,
191 | 07AFD4F71ECAD4D10015BBFA /* Frameworks */,
192 | 07AFD4F81ECAD4D10015BBFA /* Resources */,
193 | );
194 | buildRules = (
195 | );
196 | dependencies = (
197 | 07AFD4FC1ECAD4D10015BBFA /* PBXTargetDependency */,
198 | );
199 | name = TestInputNumberUITests;
200 | productName = TestInputNumberUITests;
201 | productReference = 07AFD4FA1ECAD4D10015BBFA /* TestInputNumberUITests.xctest */;
202 | productType = "com.apple.product-type.bundle.ui-testing";
203 | };
204 | /* End PBXNativeTarget section */
205 |
206 | /* Begin PBXProject section */
207 | 07AFD4CE1ECAD4D10015BBFA /* Project object */ = {
208 | isa = PBXProject;
209 | attributes = {
210 | LastUpgradeCheck = 0800;
211 | ORGANIZATIONNAME = "龙培";
212 | TargetAttributes = {
213 | 07AFD4D51ECAD4D10015BBFA = {
214 | CreatedOnToolsVersion = 8.0;
215 | DevelopmentTeam = 3TRF6DSXKA;
216 | ProvisioningStyle = Automatic;
217 | };
218 | 07AFD4EE1ECAD4D10015BBFA = {
219 | CreatedOnToolsVersion = 8.0;
220 | DevelopmentTeam = 3TRF6DSXKA;
221 | ProvisioningStyle = Automatic;
222 | TestTargetID = 07AFD4D51ECAD4D10015BBFA;
223 | };
224 | 07AFD4F91ECAD4D10015BBFA = {
225 | CreatedOnToolsVersion = 8.0;
226 | DevelopmentTeam = 3TRF6DSXKA;
227 | ProvisioningStyle = Automatic;
228 | TestTargetID = 07AFD4D51ECAD4D10015BBFA;
229 | };
230 | };
231 | };
232 | buildConfigurationList = 07AFD4D11ECAD4D10015BBFA /* Build configuration list for PBXProject "TestInputNumber" */;
233 | compatibilityVersion = "Xcode 3.2";
234 | developmentRegion = English;
235 | hasScannedForEncodings = 0;
236 | knownRegions = (
237 | en,
238 | Base,
239 | );
240 | mainGroup = 07AFD4CD1ECAD4D10015BBFA;
241 | productRefGroup = 07AFD4D71ECAD4D10015BBFA /* Products */;
242 | projectDirPath = "";
243 | projectRoot = "";
244 | targets = (
245 | 07AFD4D51ECAD4D10015BBFA /* TestInputNumber */,
246 | 07AFD4EE1ECAD4D10015BBFA /* TestInputNumberTests */,
247 | 07AFD4F91ECAD4D10015BBFA /* TestInputNumberUITests */,
248 | );
249 | };
250 | /* End PBXProject section */
251 |
252 | /* Begin PBXResourcesBuildPhase section */
253 | 07AFD4D41ECAD4D10015BBFA /* Resources */ = {
254 | isa = PBXResourcesBuildPhase;
255 | buildActionMask = 2147483647;
256 | files = (
257 | 07AFD4E91ECAD4D10015BBFA /* LaunchScreen.storyboard in Resources */,
258 | 07AFD4E61ECAD4D10015BBFA /* Assets.xcassets in Resources */,
259 | 07AFD4E41ECAD4D10015BBFA /* Main.storyboard in Resources */,
260 | );
261 | runOnlyForDeploymentPostprocessing = 0;
262 | };
263 | 07AFD4ED1ECAD4D10015BBFA /* Resources */ = {
264 | isa = PBXResourcesBuildPhase;
265 | buildActionMask = 2147483647;
266 | files = (
267 | );
268 | runOnlyForDeploymentPostprocessing = 0;
269 | };
270 | 07AFD4F81ECAD4D10015BBFA /* Resources */ = {
271 | isa = PBXResourcesBuildPhase;
272 | buildActionMask = 2147483647;
273 | files = (
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | };
277 | /* End PBXResourcesBuildPhase section */
278 |
279 | /* Begin PBXSourcesBuildPhase section */
280 | 07AFD4D21ECAD4D10015BBFA /* Sources */ = {
281 | isa = PBXSourcesBuildPhase;
282 | buildActionMask = 2147483647;
283 | files = (
284 | 07AFD4E11ECAD4D10015BBFA /* ViewController.m in Sources */,
285 | 07AFD4DE1ECAD4D10015BBFA /* AppDelegate.m in Sources */,
286 | 07AFD50E1ECAD5500015BBFA /* CustomTextField.m in Sources */,
287 | 07AFD4DB1ECAD4D10015BBFA /* main.m in Sources */,
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | };
291 | 07AFD4EB1ECAD4D10015BBFA /* Sources */ = {
292 | isa = PBXSourcesBuildPhase;
293 | buildActionMask = 2147483647;
294 | files = (
295 | 07AFD4F41ECAD4D10015BBFA /* TestInputNumberTests.m in Sources */,
296 | );
297 | runOnlyForDeploymentPostprocessing = 0;
298 | };
299 | 07AFD4F61ECAD4D10015BBFA /* Sources */ = {
300 | isa = PBXSourcesBuildPhase;
301 | buildActionMask = 2147483647;
302 | files = (
303 | 07AFD4FF1ECAD4D10015BBFA /* TestInputNumberUITests.m in Sources */,
304 | );
305 | runOnlyForDeploymentPostprocessing = 0;
306 | };
307 | /* End PBXSourcesBuildPhase section */
308 |
309 | /* Begin PBXTargetDependency section */
310 | 07AFD4F11ECAD4D10015BBFA /* PBXTargetDependency */ = {
311 | isa = PBXTargetDependency;
312 | target = 07AFD4D51ECAD4D10015BBFA /* TestInputNumber */;
313 | targetProxy = 07AFD4F01ECAD4D10015BBFA /* PBXContainerItemProxy */;
314 | };
315 | 07AFD4FC1ECAD4D10015BBFA /* PBXTargetDependency */ = {
316 | isa = PBXTargetDependency;
317 | target = 07AFD4D51ECAD4D10015BBFA /* TestInputNumber */;
318 | targetProxy = 07AFD4FB1ECAD4D10015BBFA /* PBXContainerItemProxy */;
319 | };
320 | /* End PBXTargetDependency section */
321 |
322 | /* Begin PBXVariantGroup section */
323 | 07AFD4E21ECAD4D10015BBFA /* Main.storyboard */ = {
324 | isa = PBXVariantGroup;
325 | children = (
326 | 07AFD4E31ECAD4D10015BBFA /* Base */,
327 | );
328 | name = Main.storyboard;
329 | sourceTree = "";
330 | };
331 | 07AFD4E71ECAD4D10015BBFA /* LaunchScreen.storyboard */ = {
332 | isa = PBXVariantGroup;
333 | children = (
334 | 07AFD4E81ECAD4D10015BBFA /* Base */,
335 | );
336 | name = LaunchScreen.storyboard;
337 | sourceTree = "";
338 | };
339 | /* End PBXVariantGroup section */
340 |
341 | /* Begin XCBuildConfiguration section */
342 | 07AFD5011ECAD4D10015BBFA /* Debug */ = {
343 | isa = XCBuildConfiguration;
344 | buildSettings = {
345 | ALWAYS_SEARCH_USER_PATHS = NO;
346 | CLANG_ANALYZER_NONNULL = YES;
347 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
348 | CLANG_CXX_LIBRARY = "libc++";
349 | CLANG_ENABLE_MODULES = YES;
350 | CLANG_ENABLE_OBJC_ARC = YES;
351 | CLANG_WARN_BOOL_CONVERSION = YES;
352 | CLANG_WARN_CONSTANT_CONVERSION = YES;
353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
354 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
355 | CLANG_WARN_EMPTY_BODY = YES;
356 | CLANG_WARN_ENUM_CONVERSION = YES;
357 | CLANG_WARN_INFINITE_RECURSION = YES;
358 | CLANG_WARN_INT_CONVERSION = YES;
359 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
360 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
361 | CLANG_WARN_UNREACHABLE_CODE = YES;
362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
363 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
364 | COPY_PHASE_STRIP = NO;
365 | DEBUG_INFORMATION_FORMAT = dwarf;
366 | ENABLE_STRICT_OBJC_MSGSEND = YES;
367 | ENABLE_TESTABILITY = YES;
368 | GCC_C_LANGUAGE_STANDARD = gnu99;
369 | GCC_DYNAMIC_NO_PIC = NO;
370 | GCC_NO_COMMON_BLOCKS = YES;
371 | GCC_OPTIMIZATION_LEVEL = 0;
372 | GCC_PREPROCESSOR_DEFINITIONS = (
373 | "DEBUG=1",
374 | "$(inherited)",
375 | );
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
383 | MTL_ENABLE_DEBUG_INFO = YES;
384 | ONLY_ACTIVE_ARCH = YES;
385 | SDKROOT = iphoneos;
386 | };
387 | name = Debug;
388 | };
389 | 07AFD5021ECAD4D10015BBFA /* Release */ = {
390 | isa = XCBuildConfiguration;
391 | buildSettings = {
392 | ALWAYS_SEARCH_USER_PATHS = NO;
393 | CLANG_ANALYZER_NONNULL = YES;
394 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
395 | CLANG_CXX_LIBRARY = "libc++";
396 | CLANG_ENABLE_MODULES = YES;
397 | CLANG_ENABLE_OBJC_ARC = YES;
398 | CLANG_WARN_BOOL_CONVERSION = YES;
399 | CLANG_WARN_CONSTANT_CONVERSION = YES;
400 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
401 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
402 | CLANG_WARN_EMPTY_BODY = YES;
403 | CLANG_WARN_ENUM_CONVERSION = YES;
404 | CLANG_WARN_INFINITE_RECURSION = YES;
405 | CLANG_WARN_INT_CONVERSION = YES;
406 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
407 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
408 | CLANG_WARN_UNREACHABLE_CODE = YES;
409 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
410 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
411 | COPY_PHASE_STRIP = NO;
412 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
413 | ENABLE_NS_ASSERTIONS = NO;
414 | ENABLE_STRICT_OBJC_MSGSEND = YES;
415 | GCC_C_LANGUAGE_STANDARD = gnu99;
416 | GCC_NO_COMMON_BLOCKS = YES;
417 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
418 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
419 | GCC_WARN_UNDECLARED_SELECTOR = YES;
420 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
421 | GCC_WARN_UNUSED_FUNCTION = YES;
422 | GCC_WARN_UNUSED_VARIABLE = YES;
423 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
424 | MTL_ENABLE_DEBUG_INFO = NO;
425 | SDKROOT = iphoneos;
426 | VALIDATE_PRODUCT = YES;
427 | };
428 | name = Release;
429 | };
430 | 07AFD5041ECAD4D10015BBFA /* Debug */ = {
431 | isa = XCBuildConfiguration;
432 | buildSettings = {
433 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
434 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
435 | DEVELOPMENT_TEAM = 3TRF6DSXKA;
436 | INFOPLIST_FILE = TestInputNumber/Info.plist;
437 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
438 | PRODUCT_BUNDLE_IDENTIFIER = com.WQL.TestDifferLanguage;
439 | PRODUCT_NAME = "$(TARGET_NAME)";
440 | PROVISIONING_PROFILE = "";
441 | PROVISIONING_PROFILE_SPECIFIER = "";
442 | };
443 | name = Debug;
444 | };
445 | 07AFD5051ECAD4D10015BBFA /* Release */ = {
446 | isa = XCBuildConfiguration;
447 | buildSettings = {
448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
449 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
450 | DEVELOPMENT_TEAM = 3TRF6DSXKA;
451 | INFOPLIST_FILE = TestInputNumber/Info.plist;
452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
453 | PRODUCT_BUNDLE_IDENTIFIER = com.WQL.TestDifferLanguage;
454 | PRODUCT_NAME = "$(TARGET_NAME)";
455 | PROVISIONING_PROFILE = "";
456 | PROVISIONING_PROFILE_SPECIFIER = "";
457 | };
458 | name = Release;
459 | };
460 | 07AFD5071ECAD4D10015BBFA /* Debug */ = {
461 | isa = XCBuildConfiguration;
462 | buildSettings = {
463 | BUNDLE_LOADER = "$(TEST_HOST)";
464 | DEVELOPMENT_TEAM = 3TRF6DSXKA;
465 | INFOPLIST_FILE = TestInputNumberTests/Info.plist;
466 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
467 | PRODUCT_BUNDLE_IDENTIFIER = com.WQL.TestInputNumberTests;
468 | PRODUCT_NAME = "$(TARGET_NAME)";
469 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestInputNumber.app/TestInputNumber";
470 | };
471 | name = Debug;
472 | };
473 | 07AFD5081ECAD4D10015BBFA /* Release */ = {
474 | isa = XCBuildConfiguration;
475 | buildSettings = {
476 | BUNDLE_LOADER = "$(TEST_HOST)";
477 | DEVELOPMENT_TEAM = 3TRF6DSXKA;
478 | INFOPLIST_FILE = TestInputNumberTests/Info.plist;
479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
480 | PRODUCT_BUNDLE_IDENTIFIER = com.WQL.TestInputNumberTests;
481 | PRODUCT_NAME = "$(TARGET_NAME)";
482 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestInputNumber.app/TestInputNumber";
483 | };
484 | name = Release;
485 | };
486 | 07AFD50A1ECAD4D10015BBFA /* Debug */ = {
487 | isa = XCBuildConfiguration;
488 | buildSettings = {
489 | DEVELOPMENT_TEAM = 3TRF6DSXKA;
490 | INFOPLIST_FILE = TestInputNumberUITests/Info.plist;
491 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
492 | PRODUCT_BUNDLE_IDENTIFIER = com.WQL.TestInputNumberUITests;
493 | PRODUCT_NAME = "$(TARGET_NAME)";
494 | TEST_TARGET_NAME = TestInputNumber;
495 | };
496 | name = Debug;
497 | };
498 | 07AFD50B1ECAD4D10015BBFA /* Release */ = {
499 | isa = XCBuildConfiguration;
500 | buildSettings = {
501 | DEVELOPMENT_TEAM = 3TRF6DSXKA;
502 | INFOPLIST_FILE = TestInputNumberUITests/Info.plist;
503 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
504 | PRODUCT_BUNDLE_IDENTIFIER = com.WQL.TestInputNumberUITests;
505 | PRODUCT_NAME = "$(TARGET_NAME)";
506 | TEST_TARGET_NAME = TestInputNumber;
507 | };
508 | name = Release;
509 | };
510 | /* End XCBuildConfiguration section */
511 |
512 | /* Begin XCConfigurationList section */
513 | 07AFD4D11ECAD4D10015BBFA /* Build configuration list for PBXProject "TestInputNumber" */ = {
514 | isa = XCConfigurationList;
515 | buildConfigurations = (
516 | 07AFD5011ECAD4D10015BBFA /* Debug */,
517 | 07AFD5021ECAD4D10015BBFA /* Release */,
518 | );
519 | defaultConfigurationIsVisible = 0;
520 | defaultConfigurationName = Release;
521 | };
522 | 07AFD5031ECAD4D10015BBFA /* Build configuration list for PBXNativeTarget "TestInputNumber" */ = {
523 | isa = XCConfigurationList;
524 | buildConfigurations = (
525 | 07AFD5041ECAD4D10015BBFA /* Debug */,
526 | 07AFD5051ECAD4D10015BBFA /* Release */,
527 | );
528 | defaultConfigurationIsVisible = 0;
529 | defaultConfigurationName = Release;
530 | };
531 | 07AFD5061ECAD4D10015BBFA /* Build configuration list for PBXNativeTarget "TestInputNumberTests" */ = {
532 | isa = XCConfigurationList;
533 | buildConfigurations = (
534 | 07AFD5071ECAD4D10015BBFA /* Debug */,
535 | 07AFD5081ECAD4D10015BBFA /* Release */,
536 | );
537 | defaultConfigurationIsVisible = 0;
538 | defaultConfigurationName = Release;
539 | };
540 | 07AFD5091ECAD4D10015BBFA /* Build configuration list for PBXNativeTarget "TestInputNumberUITests" */ = {
541 | isa = XCConfigurationList;
542 | buildConfigurations = (
543 | 07AFD50A1ECAD4D10015BBFA /* Debug */,
544 | 07AFD50B1ECAD4D10015BBFA /* Release */,
545 | );
546 | defaultConfigurationIsVisible = 0;
547 | defaultConfigurationName = Release;
548 | };
549 | /* End XCConfigurationList section */
550 | };
551 | rootObject = 07AFD4CE1ECAD4D10015BBFA /* Project object */;
552 | }
553 |
--------------------------------------------------------------------------------
/TestInputNumber.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TestInputNumber.xcodeproj/project.xcworkspace/xcuserdata/longpei.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coolll/SeparateTextField/b1962458dc7c55f822887382d5f2a88274b52fea/TestInputNumber.xcodeproj/project.xcworkspace/xcuserdata/longpei.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TestInputNumber.xcodeproj/xcuserdata/longpei.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
24 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/TestInputNumber.xcodeproj/xcuserdata/longpei.xcuserdatad/xcschemes/TestInputNumber.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
89 |
90 |
91 |
92 |
93 |
94 |
100 |
102 |
108 |
109 |
110 |
111 |
113 |
114 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/TestInputNumber.xcodeproj/xcuserdata/longpei.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | TestInputNumber.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 07AFD4D51ECAD4D10015BBFA
16 |
17 | primary
18 |
19 |
20 | 07AFD4EE1ECAD4D10015BBFA
21 |
22 | primary
23 |
24 |
25 | 07AFD4F91ECAD4D10015BBFA
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/TestInputNumber/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // TestInputNumber
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/TestInputNumber/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // TestInputNumber
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 |
24 | - (void)applicationWillResignActive:(UIApplication *)application {
25 | // 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.
26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
27 | }
28 |
29 |
30 | - (void)applicationDidEnterBackground:(UIApplication *)application {
31 | // 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.
32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
33 | }
34 |
35 |
36 | - (void)applicationWillEnterForeground:(UIApplication *)application {
37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
38 | }
39 |
40 |
41 | - (void)applicationDidBecomeActive:(UIApplication *)application {
42 | // 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.
43 | }
44 |
45 |
46 | - (void)applicationWillTerminate:(UIApplication *)application {
47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
48 | }
49 |
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/TestInputNumber/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/TestInputNumber/Base.lproj/LaunchScreen.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 |
--------------------------------------------------------------------------------
/TestInputNumber/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 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/TestInputNumber/CustomTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // CustomTextView.h
3 | // TestInputNumber
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | // 控件思路:http://www.jianshu.com/p/582cee0680b0
8 | // 控件下载及问题反馈至:https://github.com/Coolll/SeparateTextField
9 |
10 |
11 | #import
12 |
13 | @interface CustomTextField : UITextField
14 |
15 | - (void)configureTextFieldWithPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count;
16 |
17 | - (void)configureTextFieldWithPlaceHolder:(NSString*)placeHolder withSeparateArray:(NSArray*)countArray;
18 |
19 |
20 | //placeHoler 提示用户的文本
21 | //count 每多少个进行分割,即每隔多少个字符添加空格符号
22 | - (instancetype)initWithPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count;
23 |
24 | //frame 视图的frame
25 | //placeHoler 提示用户的文本
26 | //count 每多少个进行分割,即每隔多少个字符添加空格符号
27 | - (instancetype)initWithFrame:(CGRect)frame withPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count;
28 |
29 |
30 | //frame 视图的frame
31 | //placeHoler 提示用户的文本
32 | //array 每多少个进行分割,即每隔多少个字符添加空格符号,可不等,但是必须要是字符串对象
33 | - (instancetype)initWithFrame:(CGRect)frame withPlaceHolder:(NSString*)placeHolder withSeparateArray:(NSArray*)countArray;
34 |
35 |
36 | /**
37 | * 用户实际输入的内容
38 | **/
39 | @property (nonatomic,copy) NSString *userInputContent;
40 |
41 | /**
42 | * 限制用户实际输入的数量,默认无限制
43 | **/
44 | @property (nonatomic,assign) NSInteger limitCount;
45 |
46 |
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/TestInputNumber/CustomTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // CustomTextView.m
3 | // TestInputNumber
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | // 控件思路:http://www.jianshu.com/p/582cee0680b0
8 | // 控件下载及问题反馈至:https://github.com/Coolll/SeparateTextField
9 |
10 |
11 | #import "CustomTextField.h"
12 |
13 | //placeHolder的左侧距离
14 | static const NSInteger placeHolderLeft = 10;
15 |
16 | @interface CustomTextField ()
17 |
18 | /**
19 | * 每隔多少字符分割
20 | **/
21 | @property (nonatomic,assign) NSInteger separateCount;
22 |
23 | /**
24 | * 提示文本
25 | **/
26 | @property (nonatomic,copy) NSString *placeHolderString;
27 |
28 | /**
29 | * placeHolder
30 | **/
31 | @property (nonatomic,strong) UILabel *placeHolderLabel;
32 |
33 | /**
34 | * 尺寸
35 | **/
36 | @property (nonatomic,assign) CGRect viewFrame;
37 |
38 | /**
39 | * 分割的array
40 | **/
41 | @property (nonatomic,strong) NSMutableArray *separateArray;
42 |
43 | /**
44 | * Location
45 | **/
46 | @property (nonatomic,assign) NSInteger locationIndex;
47 |
48 |
49 |
50 | @end
51 |
52 | @implementation CustomTextField
53 |
54 | #pragma mark - 初始化
55 |
56 | - (void)configureTextFieldWithPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count
57 | {
58 | if (!_placeHolderLabel) {
59 |
60 | self.placeHolderString = placeHolder;
61 | self.separateCount = count;
62 | self.locationIndex = 0;
63 |
64 | self.delegate = self;
65 | self.keyboardType = UIKeyboardTypeNumberPad;//键盘类型
66 | self.font = [UIFont systemFontOfSize:20.0];
67 | self.tintColor = [UIColor grayColor];//光标颜色
68 | self.viewFrame = self.frame;
69 |
70 | [self loadCustomViewWithPlaceHolder:self.placeHolderString];
71 |
72 | }
73 |
74 | }
75 |
76 |
77 | - (void)configureTextFieldWithPlaceHolder:(NSString*)placeHolder withSeparateArray:(NSArray*)countArray
78 | {
79 | if (!_placeHolderLabel) {
80 |
81 | self.separateArray = [NSMutableArray arrayWithArray:countArray];
82 | self.placeHolderString = placeHolder;
83 |
84 | self.delegate = self;
85 | self.keyboardType = UIKeyboardTypeNumberPad;//键盘类型
86 | self.font = [UIFont systemFontOfSize:20.0];
87 | self.tintColor = [UIColor grayColor];//光标颜色
88 |
89 | self.viewFrame = self.frame;
90 |
91 | [self loadCustomViewWithPlaceHolder:self.placeHolderString];
92 |
93 | }
94 |
95 | }
96 |
97 |
98 | - (instancetype)initWithPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count
99 | {
100 | return [self initWithFrame:CGRectZero withPlaceHolder:placeHolder withSeparateCount:count];
101 | }
102 |
103 | - (instancetype)initWithFrame:(CGRect)frame withPlaceHolder:(NSString*)placeHolder withSeparateCount:(NSInteger)count
104 | {
105 | self = [super initWithFrame:frame];
106 |
107 | if (self) {
108 |
109 | self.separateCount = count;
110 | self.viewFrame = frame;
111 | self.placeHolderString = placeHolder;
112 | self.locationIndex = 0;
113 |
114 | self.delegate = self;
115 | self.keyboardType = UIKeyboardTypeNumberPad;//键盘类型
116 | self.font = [UIFont systemFontOfSize:20.0];
117 | self.tintColor = [UIColor grayColor];//光标颜色
118 |
119 | //左侧填充视图
120 | UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, placeHolderLeft, frame.size.height)];
121 | self.leftView = view;
122 | self.leftViewMode = UITextFieldViewModeAlways;
123 |
124 | //如果frame存在0,则不做处理
125 | if (frame.size.width != 0 && frame.size.height != 0) {
126 | [self loadCustomViewWithPlaceHolder:self.placeHolderString];
127 |
128 | }
129 |
130 |
131 | }
132 |
133 | return self;
134 | }
135 |
136 | - (instancetype)initWithFrame:(CGRect)frame withPlaceHolder:(NSString*)placeHolder withSeparateArray:(NSArray*)countArray
137 | {
138 | self = [super initWithFrame:frame];
139 |
140 | if (self) {
141 |
142 | self.separateArray = [NSMutableArray arrayWithArray:countArray];
143 | self.viewFrame = frame;
144 | self.placeHolderString = placeHolder;
145 |
146 | self.delegate = self;
147 | self.keyboardType = UIKeyboardTypeNumberPad;//键盘类型
148 | self.font = [UIFont systemFontOfSize:20.0];
149 | self.tintColor = [UIColor grayColor];//光标颜色
150 |
151 | //左侧填充视图
152 | UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, placeHolderLeft, frame.size.height)];
153 | self.leftView = view;
154 | self.leftViewMode = UITextFieldViewModeAlways;
155 |
156 | //如果frame存在0,则不做处理
157 | if (frame.size.width != 0 && frame.size.height != 0) {
158 | [self loadCustomViewWithPlaceHolder:self.placeHolderString];
159 |
160 | }
161 |
162 |
163 | }
164 |
165 | return self;
166 | }
167 |
168 | - (NSString*)userInputContent
169 | {
170 | NSString *text = self.text;
171 |
172 | NSMutableString *mutableText = [NSMutableString stringWithString:text];
173 |
174 | NSString *contentStr = [mutableText stringByReplacingOccurrencesOfString:@" " withString:@""];
175 |
176 | return contentStr;
177 | }
178 |
179 | #pragma mark - 设置frame
180 | - (void)setFrame:(CGRect)frame
181 | {
182 | [super setFrame:frame];
183 |
184 | //frame若存在0,则不处理
185 | if (frame.size.width == 0 || frame.size.height == 0 ) {
186 |
187 | return;
188 | }
189 |
190 | self.viewFrame = frame;
191 |
192 | [self loadCustomViewWithPlaceHolder:self.placeHolderString];
193 |
194 | }
195 |
196 |
197 |
198 |
199 | #pragma mark - 构建placeHolder
200 | - (void)loadCustomViewWithPlaceHolder:(NSString*)placeHolder
201 | {
202 | if (placeHolder) {
203 | //存在placeHolder文本时,则初始化
204 | _placeHolderLabel = [[UILabel alloc]init];
205 | _placeHolderLabel.frame = CGRectMake(placeHolderLeft, 0, self.viewFrame.size.width-placeHolderLeft, self.viewFrame.size.height);
206 | _placeHolderLabel.text = placeHolder;
207 | _placeHolderLabel.textColor = [UIColor lightGrayColor];
208 | [self addSubview:_placeHolderLabel];
209 |
210 | }
211 | }
212 |
213 | #pragma mark - 光标frame
214 | - (CGRect)caretRectForPosition:(UITextPosition *)position
215 | {
216 | CGRect originalRect = [super caretRectForPosition:position];
217 | originalRect.size.height = self.viewFrame.size.height/2;
218 | originalRect.size.width = 2;
219 | originalRect.origin.y = self.viewFrame.size.height/4;
220 | return originalRect;
221 | }
222 |
223 |
224 | #pragma mark - textField代理
225 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
226 | {
227 |
228 |
229 | if (![string isEqualToString:@""]) {
230 |
231 | //输入只要不是删除键,则把自定义的placeHolder隐藏了
232 | self.placeHolderLabel.hidden = YES;
233 |
234 | //处理之后的字符串
235 | NSString *dealString = [self changeStringWithOperateString:string withOperateRange:range withOriginString:textField.text];
236 |
237 | textField.text = dealString;
238 |
239 | }
240 |
241 |
242 |
243 | if ([string isEqualToString:@""]) {
244 |
245 | //处理之后的字符串
246 | NSString *dealString = [self changeStringWithOperateString:string withOperateRange:range withOriginString:textField.text];
247 |
248 | textField.text = dealString;
249 | }
250 |
251 | //设置光标位置
252 | [self setSelectedRange:NSMakeRange(self.locationIndex, 0)];
253 |
254 | if ([string isEqualToString:@""] && range.location == 0 && range.length == 1 && textField.text.length == 0) {
255 |
256 | //输入删除键后,没有字符了,把自定义的placeHolder显示了
257 | self.placeHolderLabel.hidden = NO;
258 |
259 | }
260 |
261 | return NO;
262 | }
263 |
264 |
265 |
266 |
267 | #pragma mark - 设置光标
268 |
269 | - (void) setSelectedRange:(NSRange) range
270 | {
271 | UITextPosition* beginning = self.beginningOfDocument;
272 |
273 | UITextPosition* startPosition = [self positionFromPosition:beginning offset:range.location];
274 | UITextPosition* endPosition = [self positionFromPosition:beginning offset:range.location + range.length];
275 | UITextRange* selectionRange = [self textRangeFromPosition:startPosition toPosition:endPosition];
276 |
277 | [self setSelectedTextRange:selectionRange];
278 | }
279 |
280 |
281 | #pragma mark - 核心处理方法
282 |
283 | - (NSString*)changeStringWithOperateString:(NSString*)string withOperateRange:(NSRange)range withOriginString:(NSString*)originString
284 | {
285 |
286 | self.locationIndex = range.location;
287 |
288 | //原始字符串
289 | NSMutableString *originStr = [NSMutableString stringWithString:originString];
290 |
291 | //截取操作的位置之前的字符串
292 | NSMutableString *subStr = [NSMutableString stringWithString:[originStr substringToIndex:range.location]];
293 | //光标前的字符串 剔除空格符号
294 | NSString *subNoSpace = [subStr stringByReplacingOccurrencesOfString:@" " withString:@""];
295 |
296 | //得到操作处前面 空格的总数目
297 | NSInteger originSpaceCount = subStr.length-subNoSpace.length;
298 |
299 | if ([string isEqualToString:@""]) {
300 |
301 | //删除字符
302 | [originStr deleteCharactersInRange:range];
303 |
304 | }else{
305 |
306 |
307 | NSMutableString *originMutableStr = [NSMutableString stringWithString:originString];
308 | NSString *originNoString = [originMutableStr stringByReplacingOccurrencesOfString:@" " withString:@""];
309 | if (self.limitCount > 0 && originNoString.length >= self.limitCount) {
310 |
311 | return originString;
312 | }
313 |
314 |
315 |
316 | //插入字符
317 | [originStr insertString:string atIndex:range.location];
318 |
319 | //插入后,index要加1
320 | self.locationIndex += 1;
321 |
322 | }
323 |
324 | NSString *originNoSpaceString = [originStr stringByReplacingOccurrencesOfString:@" " withString:@""];
325 |
326 | //原始字符串,全部剔除空格
327 | NSMutableString *newString = [NSMutableString stringWithString:originNoSpaceString];
328 |
329 |
330 | if (self.separateCount > 0) {
331 |
332 | //如果是等量分割
333 | for (NSInteger i = newString.length; i > 0; i--) {
334 |
335 | if (i%self.separateCount == 0) {
336 | //插入空格符
337 | [newString insertString:@" " atIndex:i];
338 | }
339 | }
340 |
341 | }
342 |
343 |
344 | if (self.separateArray.count > 0) {
345 |
346 | //应该操作的index
347 | NSMutableArray *indexArray = [NSMutableArray array];
348 |
349 | NSInteger currentIndex = 0;
350 |
351 | for (int i = 0; i< self.separateArray.count; i++) {
352 |
353 | //从用户设置的数组中取值
354 | id object = self.separateArray[i];
355 |
356 | if ([object isKindOfClass:[NSString class]]) {
357 | //第n次按照多少个分隔
358 | NSInteger count = [object integerValue];
359 | //累加
360 | currentIndex += count;
361 | //拿到分割处的index
362 | NSNumber *indexNumber = [NSNumber numberWithInteger:currentIndex];
363 |
364 | //添加到数组中
365 | [indexArray addObject:indexNumber];
366 | }
367 |
368 | }
369 |
370 |
371 | //倒序插入空格符
372 | for (NSInteger j = indexArray.count-1; j >=0 ; j--) {
373 |
374 | NSNumber *indexObject = indexArray[j];
375 |
376 | NSInteger index = [indexObject integerValue];
377 |
378 | //不可越界
379 | if (index < newString.length) {
380 |
381 | [newString insertString:@" " atIndex:index];
382 |
383 | }
384 | }
385 |
386 |
387 |
388 | }
389 |
390 |
391 | NSString *newSubString;
392 |
393 | if (self.locationIndex > newString.length) {
394 | //如果是删除最后一位数字,且数字的左侧为空格时,防止越界
395 | newSubString = [NSString stringWithFormat:@"%@",newString];
396 |
397 | self.locationIndex -= 1 ;
398 | }else{
399 |
400 | //添加字符后,光标的左侧文本
401 | newSubString = [newString substringToIndex:self.locationIndex];
402 |
403 | }
404 |
405 | //光标左侧文本
406 | NSMutableString *newSubMutableString = [NSMutableString stringWithString:newSubString];
407 |
408 | //将操作后的左侧文本 剔除空格
409 | NSString *newNoSpaceString = [newSubMutableString stringByReplacingOccurrencesOfString:@" " withString:@""];
410 |
411 | //操作后的左侧文本,空格的数量
412 | NSInteger newSpaceCount = newSubString.length - newNoSpaceString.length;
413 |
414 | //如果操作前的空格数量等于操作后的空格数量
415 | if (originSpaceCount == newSpaceCount) {
416 |
417 |
418 | if ([string isEqualToString:@""]) {
419 |
420 | //删除的时候,如果删了该数字后,左侧为空格,则需要光标再左移1位
421 | if (range.location > 0) {
422 |
423 | NSString *originSubS = [originStr substringWithRange:NSMakeRange(range.location-1, 1)];
424 |
425 | if ([originSubS isEqualToString:@" "]) {
426 |
427 | self.locationIndex -= 1;
428 | }
429 | }
430 |
431 | }
432 |
433 | }else{
434 |
435 | //如果操作前的空格数量不等于操作后的空格数量,说明新增文本前,又添加了空格,需要将光标右移1位
436 | if ([string isEqualToString:@""]) {
437 |
438 |
439 | }else{
440 | self.locationIndex += 1;
441 |
442 | }
443 |
444 | }
445 |
446 |
447 | return newString;
448 | }
449 |
450 | @end
451 |
--------------------------------------------------------------------------------
/TestInputNumber/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/TestInputNumber/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // TestInputNumber
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/TestInputNumber/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // TestInputNumber
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | // 控件思路:http://www.jianshu.com/p/582cee0680b0
8 | // 控件下载及问题反馈至:https://github.com/Coolll/SeparateTextField
9 |
10 | #import "ViewController.h"
11 | #import "CustomTextField.h"
12 |
13 | @interface ViewController ()
14 | {
15 | CustomTextField *viewOne;
16 | CustomTextField *viewTwo;
17 | CustomTextField *viewThree;
18 | __weak IBOutlet CustomTextField *dddTextField;
19 |
20 | }
21 | @end
22 |
23 | @implementation ViewController
24 |
25 | - (void)viewDidLoad {
26 | [super viewDidLoad];
27 |
28 | [self loadTextFieldWithFrame];
29 |
30 | }
31 |
32 | - (void)loadTextFieldWithFrame
33 | {
34 |
35 | //固定4个进行分隔
36 | viewOne = [[CustomTextField alloc]initWithFrame:CGRectMake(20, 200, 300, 50) withPlaceHolder:@"请输入银行卡号" withSeparateCount:4];
37 | viewOne.limitCount = 19;//可以不设置,但是那样的话,就可以无限输入了
38 | viewOne.layer.cornerRadius = 4.0;
39 | viewOne.layer.borderColor = [UIColor lightGrayColor].CGColor;
40 | viewOne.layer.borderWidth = 2.0;
41 | [self.view addSubview:viewOne];
42 |
43 |
44 | //按照数组中的进行分隔,假如分隔电话号码@[@"3",@"4",@"4"]即可
45 | viewTwo = [[CustomTextField alloc]initWithFrame:CGRectMake(20, 300, 300, 50) withPlaceHolder:@"请输入电话号码" withSeparateArray:@[@"3",@"4",@"4"]];
46 | viewTwo.limitCount = 11;//可以不设置,但是那样的话,就可以无限输入了
47 | viewTwo.layer.cornerRadius = 4.0;
48 | viewTwo.layer.borderColor = [UIColor lightGrayColor].CGColor;
49 | viewTwo.layer.borderWidth = 2.0;
50 | [self.view addSubview:viewTwo];
51 |
52 |
53 | //输入身份证号
54 | viewThree = [[CustomTextField alloc]initWithFrame:CGRectMake(20, 400, 300, 50) withPlaceHolder:@"请输入身份证号" withSeparateArray:@[@"6",@"8",@"4"]];
55 | viewThree.limitCount = 18;//可以不设置,但是那样的话,就可以无限输入了
56 | viewThree.layer.cornerRadius = 4.0;
57 | viewThree.layer.borderColor = [UIColor lightGrayColor].CGColor;
58 | viewThree.layer.borderWidth = 2.0;
59 | [self.view addSubview:viewThree];
60 |
61 | }
62 | #pragma mark - 使用xib文件需实现该方法
63 |
64 | - (void)viewDidLayoutSubviews
65 | {
66 | //使用Xib加载时,配置等个数分隔
67 | [dddTextField configureTextFieldWithPlaceHolder:@"输入密码" withSeparateCount:4];
68 |
69 | //使用Xib加载时,按照数组分隔
70 | //[dddTextField configureTextFieldWithPlaceHolder:@"使用Xib,请输入订单号" withSeparateArray:@[@"3",@"4",@"5",@"6"]];
71 |
72 | }
73 |
74 |
75 |
76 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
77 | {
78 | NSLog(@"实际输入银行卡内容:%@",viewOne.userInputContent);
79 |
80 | NSLog(@"实际输入电话内容:%@",viewTwo.userInputContent);
81 |
82 | NSLog(@"实际输入身份证号内容:%@",viewThree.userInputContent);
83 | }
84 |
85 |
86 |
87 | - (void)didReceiveMemoryWarning {
88 | [super didReceiveMemoryWarning];
89 | // Dispose of any resources that can be recreated.
90 | }
91 |
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/TestInputNumber/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // TestInputNumber
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/TestInputNumberTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TestInputNumberTests/TestInputNumberTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestInputNumberTests.m
3 | // TestInputNumberTests
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TestInputNumberTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation TestInputNumberTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/TestInputNumberUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TestInputNumberUITests/TestInputNumberUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestInputNumberUITests.m
3 | // TestInputNumberUITests
4 | //
5 | // Created by 龙培 on 17/5/16.
6 | // Copyright © 2017年 龙培. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TestInputNumberUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation TestInputNumberUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/imageFile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coolll/SeparateTextField/b1962458dc7c55f822887382d5f2a88274b52fea/imageFile.png
--------------------------------------------------------------------------------