I keep seeing that people don't know how to properly determine the resulting string when implementing shouldChangeCharactersInRange.
Here's how you get the new text that would be entered if you returned YES:
NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
Once you have this new text, it's easy to check if that text is a valid number or not, and return YES or NO accordingly.
Keep in mind that all other solutions, such as those shown here, where one checks the length of "string", and such, may not work properly if the user tries to edit the string using a bluetooth keyboard with cursor keys or using the advanced editing features (select, cut, paste).