Reputation: 101
http://sublime.nyasha.me/admin/form_masks.html
I use this technique to achieve nice results with html/css/java etc, but how does one achieve this in objective-c?
I've read so far about number formatting, but how can I literally have it so when the content is editable it displays the formatted version as they're typing and doesn't allow them to exceed .length
in certain areas.
My example I need to use it for is
00:00:00
or 00h:00m:00s
so when edited it will achieve __:__:__
or __h:__m:__s
I've been scraping through the interwebs and cannot find such a technique, so far I've considered programatically doing something like this..
3x UITextField
1x UILabel
if (editing is commenced && value changed) {
if (.length == 2) {
Move onto next UITextField;
}
}
And display the UILabel Masked over the textfields, but also customise the textfields so 3 appears to be one.
-- EDIT
//Programming the Textfield Mask
-(void)reformatAsCardNumber:(UITextField *)textField
{
NSUInteger targetCursorPosition =
[textField offsetFromPosition:textField.beginningOfDocument
toPosition:textField.selectedTextRange.start];
NSString *cardNumberWithoutSpaces =
[self removeNonDigits:textField.text
andPreserveCursorPosition:&targetCursorPosition];
if ([cardNumberWithoutSpaces length] > 6) {
[textField setText:previousTextFieldContent];
textField.selectedTextRange = previousSelection;
return;
}
NSString *cardNumberWithSpaces =
[self insertSpacesEveryFourDigitsIntoString:cardNumberWithoutSpaces
andPreserveCursorPosition:&targetCursorPosition];
textField.text = cardNumberWithSpaces;
UITextPosition *targetPosition =
[textField positionFromPosition:[textField beginningOfDocument]
offset:targetCursorPosition];
[textField setSelectedTextRange:
[textField textRangeFromPosition:targetPosition
toPosition:targetPosition]
];
}
-(BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
previousTextFieldContent = textField.text;
previousSelection = textField.selectedTextRange;
return YES;
}
- (NSString *)removeNonDigits:(NSString *)string
andPreserveCursorPosition:(NSUInteger *)cursorPosition
{
NSUInteger originalCursorPosition = *cursorPosition;
NSMutableString *digitsOnlyString = [NSMutableString new];
for (NSUInteger i=0; i<[string length]; i++) {
unichar characterToAdd = [string characterAtIndex:i];
if (isdigit(characterToAdd)) {
NSString *stringToAdd =
[NSString stringWithCharacters:&characterToAdd
length:1];
[digitsOnlyString appendString:stringToAdd];
}
else {
if (i < originalCursorPosition) {
(*cursorPosition)--;
}
}
}
return digitsOnlyString;
}
- (NSString *)insertSpacesEveryFourDigitsIntoString:(NSString *)string
andPreserveCursorPosition:(NSUInteger *)cursorPosition
{
NSMutableString *stringWithAddedSpaces = [NSMutableString new];
NSUInteger cursorPositionInSpacelessString = *cursorPosition;
for (NSUInteger i=0; i<[string length]; i++) {
if ((i>0) && ((i % 2) == 0)) {
[stringWithAddedSpaces appendString:@":"];
if (i < cursorPositionInSpacelessString) {
(*cursorPosition)++;
}
}
unichar characterToAdd = [string characterAtIndex:i];
NSString *stringToAdd =
[NSString stringWithCharacters:&characterToAdd length:1];
[stringWithAddedSpaces appendString:stringToAdd];
}
return stringWithAddedSpaces;
}
Then to call it
[_answerTextField addTarget:self
action:@selector(reformatAsCardNumber:)
forControlEvents:UIControlEventEditingChanged];
I need the pre-determined text such as __:__:__
or preferably __h:__m:__s
so when you start typing you get 00h:0_m:__
as you fill out.
As right now, I get `` then when I start typing I get 00:0
etc..
Upvotes: 3
Views: 2457
Reputation: 50109
Use the textFieldShouldChange method to modify the input / move the cursor as you see fit BEFORE it is updated on the screen
UITextFieldDelegate
:textField:shouldChangeCharactersInRange:replacementString:
Asks the delegate if the specified text should be changed.
The text field calls this method whenever the user types a new character in the text field or deletes an existing character.
in addition there is also textDidChange in the delegate which works AFTER the text is shown
these are DELEGATE methods so you have to become the textField's delegate:
//1 conform to the delegate
@interface MyViewController <UITextFieldDelegate>
then
//2 set yourself as delegate (can also be done through IB)
textView.delegate = self;
Upvotes: 3