iOS开发iOS大牛修炼之路ios新知识

[译] iOS:NSScanner,一个陌生的条件判断利器!

2016-05-24  本文已影响2580人  以技术之名

NSScanner官方文档

NSScanner类是一个类簇的抽象父类,该类簇为一个从NSString对象扫描值的对象提供了程序接口。

NSScanner对象把NSString 对象的的字符解释和转化成 number和string 类型的值。在创建NSScanner对象的时候为它分配字符(string ),当你从NSScanner对象获取内容的时候,它会从头到尾遍历字符串(string)。

由于类簇的属性, scanner对象并不是 NSScanner类的实例,而是它一个私有子类的实例。尽管scanner对象的类是私有的,但是它的接口是公开的(抽象父类已经声明)。 NSScanner 的原始方法是string和Configuring a Scanner方法下面列举的所有的方法。

在 NSScanner 对象扫描字符串的时候,你可以通过设置属性charactersToBeSkipped忽略某些字符。在扫描字符串之前,那些位于忽略字符集中的字符将会被跳过。默认的忽略字符是空格回车字符。

可以通过[[scanner string] substringFromIndex:[scanner scanLocation]]获取未扫描的字符串。

创建 Scanner对象

+ (instancetype)scannerWithString:(NSString *)aString

+ (id)localizedScannerWithString:(NSString *)aString

- (instancetype)initWithString:(NSString *)aString

获取Scanner的字符串

@property(readonly, copy) NSString *string

配置Scanner

@property NSUInteger scanLocation
@property BOOL caseSensitive
@property(copy) NSCharacterSet *charactersToBeSkipped
@property(retain) id locale

扫描字符串

- (BOOL)scanCharactersFromSet:(NSCharacterSet *)scanSet   intoString:(NSString * _Nullable *)stringValue;
- (BOOL)scanUpToCharactersFromSet:(NSCharacterSet *)stopSet    intoString:(NSString * _Nullable *)stringValue;
- (BOOL)scanString:(NSString *)string  intoString:(NSString * _Nullable *)stringValue;
- (BOOL)scanUpToString:(NSString *)stopString   intoString:(NSString * _Nullable *)stringValue;
- (BOOL)scanDecimal:(NSDecimal *)decimalValue;
- (BOOL)scanDouble:(double *)doubleValue;
- (BOOL)scanFloat:(float *)floatValue;
- (BOOL)scanHexDouble:(double *)result;
- (BOOL)scanHexFloat:(float *)result;
- (BOOL)scanHexInt:(unsigned int *)intValue;
- (BOOL)scanHexLongLong:(unsigned long long *)result;
- (BOOL)scanInt:(int *)intValue;
- (BOOL)scanInteger:(NSInteger *)value;
- (BOOL)scanUnsignedLongLong:(unsigned long long *)unsignedLongLongValue;
@property(getter=isAtEnd, readonly) BOOL atEnd;

实例:

#import <Foundation/Foundation.h>

@interface ConditionJudgmentController : NSObject
//输入框中只能输入数字和小数点,且小数点只能输入一位,参数number 可以设置小数的位数,该函数在-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string调用;
+(BOOL)isValidAboutInputText:(UITextField *)textfield shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string  decimalNumber: (NSInteger) number;
@end
#import "ConditionJudgmentController.h"

@implementation ConditionJudgmentController


+(BOOL)isValidAboutInputText:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string decimalNumber:(NSInteger)number{

    NSScanner      *scanner    = [NSScanner scannerWithString:string];
    NSCharacterSet *numbers;
    NSRange         pointRange = [textField.text rangeOfString:@"."];
    if ( (pointRange.length > 0) && (pointRange.location < range.location  || pointRange.location > range.location + range.length) ){
        numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    }else{
        numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789."];
    }
    if ( [textField.text isEqualToString:@""] && [string isEqualToString:@"."] ){
        return NO;
    }
    short remain = number; //保留 number位小数
    NSString *tempStr = [textField.text stringByAppendingString:string];
    NSUInteger strlen = [tempStr length];
    if(pointRange.length > 0 && pointRange.location > 0){ //判断输入框内是否含有“.”。
        if([string isEqualToString:@"."]){ //当输入框内已经含有“.”时,如果再输入“.”则被视为无效。
            return NO;
        }
        if(strlen > 0 && (strlen - pointRange.location) > remain+1){ //当输入框内已经含有“.”,当字符串长度减去小数点前面的字符串长度大于需要要保留的小数点位数,则视当次输入无效。
            return NO;
        }
    }
    NSRange zeroRange = [textField.text rangeOfString:@"0"];
    if(zeroRange.length == 1 && zeroRange.location == 0){ //判断输入框第一个字符是否为“0”
        if(![string isEqualToString:@"0"] && ![string isEqualToString:@"."] && [textField.text length] == 1){ //当输入框只有一个字符并且字符为“0”时,再输入不为“0”或者“.”的字符时,则将此输入替换输入框的这唯一字符。
            textField.text = string;
            return NO;
        }else{
            if(pointRange.length == 0 && pointRange.location > 0){ //当输入框第一个字符为“0”时,并且没有“.”字符时,如果当此输入的字符为“0”,则视当此输入无效。
                if([string isEqualToString:@"0"]){
                    return NO;
                }
            }
        }
    }
    NSString *buffer;
    if ( ![scanner scanCharactersFromSet:numbers intoString:&buffer] && ([string length] != 0) ){
        return NO;
    }else{
        return YES;
    }
}

@end

注意:上面的方法要结合UITextField的代理方法使用

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    return [ConditionJudgmentController isValidAboutInputText:textField shouldChangeCharactersInRange:range replacementString:string decimalNumber:3];
}

结束语:
平时读者在进行条件判断时,可能使用正则表达式或者用if语句比较多一点,其实NSScanner类为我们提供了一个非常好的方式进行判断。把它们结合起来使用,可以获得更好的效果。

上一篇下一篇

猜你喜欢

热点阅读