0

I have an integer value that spans a range so large it is impractical to use a slider, as it lacks the sensitivity to pick out an exact value in that range.

I used a PSTextFieldSpecifier instead, and set the keyboard to Numbers. However, in Settings.app, the copy and paste function allows text to be inserted into what should be a numeric field.

Does anyone have a solution to the problem?

4

1 回答 1

1

I have always implemented this with a custom

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

routine. You monitor the characters as they come in and only accept the numerics.

I used a UITextField, and implemented the UITextFieldDelegate methods outlined below:

// This method enforces the textField to give up first responder and return
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
    [textField resignFirstResponder];
    return YES;
}

// This method copies the current UITextField' text into a string used for editing
// comparing, and for if a cancelation occurs we can replace with the original text
-(void)textFieldDidBeginEditing:(UITextField *)textField{
    initialValueWhenEntering = [NSString stringWithString:textField.text];
    [initialValueWhenEntering retain];
}

// This routine enforces that only a single period or numerics be taken into the new
// value for the input
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

    unsigned int stringLength = (unsigned int)[textField.text lengthOfBytesUsingEncoding:NSASCIIStringEncoding];
    unsigned int counter;
    unsigned int periodCounter = 0;

    // Test to make sure there wasnt already some periods in the initial string
    for(counter = 0; counter < stringLength; counter++){
        if(   [textField.text characterAtIndex:(NSUInteger)counter] != '.' && 
            ( [textField.text characterAtIndex:(NSUInteger)counter] < '0' ||
              [textField.text characterAtIndex:(NSUInteger)counter] > '9' ) ){
            return NO;
        }else if( [textField.text characterAtIndex:(NSUInteger)counter] == '.' ){
            periodCounter++;
        }
    }

    stringLength = (unsigned int)[string lengthOfBytesUsingEncoding:NSASCIIStringEncoding];
    for(counter = 0; counter < stringLength; counter++){
        if(   [string characterAtIndex:(NSUInteger)counter] != '.' && 
            ( [string characterAtIndex:(NSUInteger)counter] < '0' || [string characterAtIndex:(NSUInteger)counter] > '9' ) ){
            return NO;
        }else if( [string characterAtIndex:(NSUInteger)counter] == '.' ){
            periodCounter++;
        }
    }

    if( periodCounter <= 1 ){
        return YES;
    }else{
        return NO;
    }
}

And finally the routine that gets automatically called when the textfield has ended editing

-(void)textFieldDidEndEditing:(UITextField *)textField{
    unsigned int stringLength = (unsigned int)[textField.text
                                lengthOfBytesUsingEncoding:NSASCIIStringEncoding];
    unsigned int counter;

    if( 0 == stringLength ){
        textField.text = initialValueWhenEntering;

        float temperature = [textField.text floatValue];

        // Set the temperature of all element boxes
        for(counter = MIN_ELEMENT_INDEX; counter <= MAX_ELEMENT_INDEX; counter++){
            [periodicButtons[counter] setOutputType:myGraphType aValue:temperature];
        }
    }else if( 1 == stringLength ){
        if( [textField.text characterAtIndex:(NSUInteger)0] == '.' ){
            textField.text = initialValueWhenEntering;
        }

        float temperature = [textField.text floatValue];

        textField.text = [NSString stringWithFormat:@"%.2f", temperature];

        // Set the temperature of all element boxes
        for(counter = MIN_ELEMENT_INDEX; counter <= MAX_ELEMENT_INDEX; counter++){
            [periodicButtons[counter] setOutputType:myGraphType aValue:temperature];
        }
    }else{ // Should be a semi-valid number at this point
        float temperature = [textField.text floatValue];

        if( temperature > 5900.0 ){
            temperature = 5900.0;
        }

        textField.text = [NSString stringWithFormat:@"%.2f", temperature];

        // Set the temperature of all element boxes
        for(counter = MIN_ELEMENT_INDEX; counter <= MAX_ELEMENT_INDEX; counter++){
            [periodicButtons[counter] setOutputType:myGraphType aValue:temperature];
        }
    }

    [initialValueWhenEntering release];
}

In my example, I did perform value limit checking, but this code could be deleted.

于 2012-06-12T17:48:32.013 回答