The solution ultimately turned out to be fairly trivial. Unfortunately a lot of the questions and answers related to this question are about validating or formatting numeric values, not controlling what a user could input.
The following implementation of the shouldChangeCharactersInRange delegate method is my solution. As always, regular expressions rock in this situation. RegExLib.com is an excellent source for useful RegEx samples or solutions. I'm not a RegEx guru and always struggle a bit putting them together so any suggestions to improve it are welcome.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.quantityTextField)
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
NSString *expression = @"^([0-9]+)?(\\.([0-9]{1,2})?)?$";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression
options:NSRegularExpressionCaseInsensitive
error:nil];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:newString
options:0
range:NSMakeRange(0, [newString length])];
if (numberOfMatches == 0)
return NO;
}
return YES;
}
The above code allows the user to input these kinds of values: 1, 1.1, 1.11, .1, .11. Notice that this implementation does not replace the text field's string, which would causes a recursion. This solution simply rejects the next character the user inputs if the 'newString' does not match the regex.