版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.12.15 |
前言
NSString是我們經(jīng)常使用的一個類瓤漏,但是蘋果的API很多用起來不是那么方便,需要根據(jù)我們特殊需求進行個性化的改變和定制颊埃,接下來蔬充,我就寫一個NSString分類工具,以后在使用的時候直接調(diào)用這個分類中的方法竟秫,可以實現(xiàn)很多小的功能,用起來也很方便跷乐。相關(guān)代碼已經(jīng)上傳至GitHub - 刀客傳奇肥败。
計算字符串的占的寬度
很多時候,我們需要計算UILabel
或者UIButton
的寬度愕提,因為里面的文字可能是從服務(wù)器返回的馒稍,所以要求這個控件的寬度也是自適應(yīng)的,這就需要我們實時的計算返回的字符串占的寬度浅侨。
先看下面的代碼纽谒。
//根據(jù)字符串長度獲取字符串尺寸
- (CGSize)jj_textSizeWithFont:(UIFont *)font
constrainedToSize:(CGSize)size;
//根據(jù)字符串長度獲取字符串尺寸
- (CGSize)jj_textSizeWithFont:(UIFont *)font
constrainedToSize:(CGSize)size
{
CGSize textSize;
if (CGSizeEqualToSize(size, CGSizeZero)) {
NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
textSize = [self sizeWithAttributes:attributes];
textSize = CGSizeMake(floor(size.width), floor(size.height));
}
else {
NSStringDrawingOptions option = NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
//NSStringDrawingTruncatesLastVisibleLine如果文本內(nèi)容超出指定的矩形限制,文本將被截去并在最后一個字符后加上省略號如输。 如果指定了NSStringDrawingUsesLineFragmentOrigin選項鼓黔,則該選項被忽略 NSStringDrawingUsesFontLeading計算行高時使用行間距。(譯者注:字體大小+行間距=行高)
NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
CGRect rect = [self boundingRectWithSize:size options:option attributes:attributes context:nil];
textSize = rect.size;
//注意:當(dāng)字符串同時存在@和&字符時不见,使用NSStringDrawingUsesLineFragmentOrigin時rect會變?yōu)榱? if (CGSizeEqualToSize(textSize, CGSizeZero)) {
option = NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesFontLeading;
rect = [self boundingRectWithSize:size options:option attributes:attributes context:nil];
textSize = rect.size;
}
}
return textSize;
}
下面我們就調(diào)用一下澳化。
#import "ViewController.h"
#import "NSString+JJNSStringExt.h"
@interface ViewController ()
@end
@implementation ViewController
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor lightGrayColor];
NSString *str = @"我們是一家人";
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:button];
[button setTitle:str forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:17.0];
button.backgroundColor = [UIColor blueColor];
CGSize size = [str jj_textSizeWithFont:button.titleLabel.font constrainedToSize:CGSizeMake(MAXFLOAT, 22.0)];
button.frame = CGRectMake(100.0, 150.0, size.width + 20.0, 30.0);
NSLog(@"button = %@", button);
}
@end
下面看一下輸出結(jié)果
2017-12-15 23:46:56.149169+0800 JJNSStringTool[1259:19762] button = <UIButton: 0x7ffa9fc07ee0; frame = (100 150; 123.938 30); opaque = NO; layer = <CALayer: 0x604000222340>>
下面看一下效果圖
判斷是否是手機號
先看分類方法
//是否是手機號的判定
- (BOOL)jj_isPhoneNumberWithStr:(NSString *)str;
/*
是否是手機號的判定
移動:139 138 137 136 135 134 147 188 187 184 183 182 178 159 158 157 152 151 150 1703 1705 1706 198
聯(lián)通:186 185 176 145 156 155 132 131 130 175 176 1704 1707 1708 1709 171 166
電信:189 181 180 177 153 133 173 1700 1701 1702 199
*/
- (BOOL)jj_isPhoneNumberWithStr:(NSString *)str
{
str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
if (str.length != 11) {
return NO;
}
else {
//移動
NSString *CM_NUM = @"^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8])|(198))\\d{8}|(170[3,5,6])\\d{7}$";
//聯(lián)通
NSString *CU_NUM = @"^((13[0-2])|(145)|(15[5-6])|(17[5,6])|(18[5,6])|(166))\\d{8}|(170[4,7-9])\\d{7}|171[0-9]\\d{7}$";
//電信
NSString *CT_NUM = @"^((133)|(153)|(17[3,7])|(18[0,1,9])|(199))\\d{8}|(170[0-2])\\d{7}$";
NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM_NUM];
BOOL isMatch1 = [pred1 evaluateWithObject:str];
NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU_NUM];
BOOL isMatch2 = [pred2 evaluateWithObject:str];
NSPredicate *pred3 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT_NUM];
BOOL isMatch3 = [pred3 evaluateWithObject:str];
if (isMatch1 || isMatch2 || isMatch3) {
return YES;
}
else {
return NO;
}
}
}
下面看調(diào)用過程
NSString *str = @"18613546782";
BOOL result = [str jj_isPhoneNumberWithStr:str];
NSLog(@"result = %d", result);
NSString *str1 = @"11111111111";
BOOL result1 = [str1 jj_isPhoneNumberWithStr:str1];
NSLog(@"result1 = %d", result1);
下面看輸出結(jié)果
2017-12-16 00:21:15.543055+0800 JJNSStringTool[1675:35852] result = 1
2017-12-16 00:21:15.543518+0800 JJNSStringTool[1675:35852] result1 = 0
可見,可以實現(xiàn)對手機號碼的判定稳吮。
身份證號碼的驗證
還是直接看代碼
//身份證號碼驗證
- (BOOL)jj_isCardIdValid;
//身份證號碼驗證
- (BOOL)jj_isCardIdValid
{
NSString * cardId = self;
cardId = [cardId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSUInteger length =0;
if (!cardId) {
return NO;
}
else {
length = cardId.length;
if (length !=15 && length !=18) {
return NO;
}
}
// 省份代碼
NSArray *areasArray =@[@"11",@"12", @"13",@"14", @"15",@"21", @"22",@"23", @"31",@"32", @"33",@"34", @"35",@"36", @"37",@"41", @"42",@"43", @"44",@"45", @"46",@"50", @"51",@"52", @"53",@"54", @"61",@"62", @"63",@"64", @"65",@"71", @"81",@"82", @"91"];
NSString *valueStart2 = [cardId substringToIndex:2];
BOOL areaFlag =NO;
for (NSString *areaCode in areasArray) {
if ([areaCode isEqualToString:valueStart2]) {
areaFlag =YES;
break;
}
}
if (!areaFlag) {
return false;
}
NSRegularExpression *regularExpression;
NSUInteger numberofMatch;
int year =0;
switch (length) {
case 15:
year = [cardId substringWithRange:NSMakeRange(6,2)].intValue +1900;
if (year %4 ==0 || (year %100 ==0 && year %4 ==0)) {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$"
options:NSRegularExpressionCaseInsensitive
error:nil];//測試出生日期的合法性
}
else {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$"
options:NSRegularExpressionCaseInsensitive
error:nil];//測試出生日期的合法性
}
numberofMatch = [regularExpression numberOfMatchesInString:cardId
options:NSMatchingReportProgress
range:NSMakeRange(0, cardId.length)];
if(numberofMatch >0) {
return YES;
}
else {
return NO;
}
case 18:
year = [cardId substringWithRange:NSMakeRange(6,4)].intValue;
if (year %4 ==0 || (year %100 ==0 && year %4 ==0)) {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$"
options:NSRegularExpressionCaseInsensitive
error:nil];//測試出生日期的合法性
}
else {
regularExpression = [[NSRegularExpression alloc]initWithPattern:@"^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$"
options:NSRegularExpressionCaseInsensitive
error:nil];//測試出生日期的合法性
}
numberofMatch = [regularExpression numberOfMatchesInString:cardId
options:NSMatchingReportProgress
range:NSMakeRange(0, cardId.length)];
if(numberofMatch >0) {
int S = ([cardId substringWithRange:NSMakeRange(0,1)].intValue + [cardId substringWithRange:NSMakeRange(10,1)].intValue) *7 +
([cardId substringWithRange:NSMakeRange(1,1)].intValue + [cardId substringWithRange:NSMakeRange(11,1)].intValue) *9 +
([cardId substringWithRange:NSMakeRange(2,1)].intValue + [cardId substringWithRange:NSMakeRange(12,1)].intValue) *10 +
([cardId substringWithRange:NSMakeRange(3,1)].intValue + [cardId substringWithRange:NSMakeRange(13,1)].intValue) *5 +
([cardId substringWithRange:NSMakeRange(4,1)].intValue + [cardId substringWithRange:NSMakeRange(14,1)].intValue) *8 +
([cardId substringWithRange:NSMakeRange(5,1)].intValue + [cardId substringWithRange:NSMakeRange(15,1)].intValue) *4 +
([cardId substringWithRange:NSMakeRange(6,1)].intValue + [cardId substringWithRange:NSMakeRange(16,1)].intValue) *2 +
[cardId substringWithRange:NSMakeRange(7,1)].intValue *1 + [cardId substringWithRange:NSMakeRange(8,1)].intValue *6 +
[cardId substringWithRange:NSMakeRange(9,1)].intValue *3;
int Y = S %11;
NSString *M =@"F";
NSString *JYM =@"10X98765432";
M = [JYM substringWithRange:NSMakeRange(Y,1)];// 判斷校驗位
if ([M isEqualToString:[cardId substringWithRange:NSMakeRange(17,1)]]) {
return YES;// 檢測ID的校驗位
}
else {
return NO;
}
}
else {
return NO;
}
default:
return NO;
}
return NO;
}
下面我們就看一下調(diào)用過程
NSString *str1 = @"990606198808183611";
BOOL result1 = [str1 jj_isCardIdValid];
NSLog(@"result1 = %d", result1);
下面看輸出結(jié)果
2017-12-16 00:39:31.180822+0800 JJNSStringTool[2099:49567] result1 = 0
正確的身份證號碼我就不去驗證了缎谷,大家可以自行去驗證。
判斷是否是整數(shù)
還是直接看代碼
// 判斷是否是整數(shù)
- (BOOL)jj_isIntNumber;
// 判斷是否是整數(shù)
- (BOOL)jj_isIntNumber
{
NSString *regex = @"^-?[0-9]\\d*$";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
return [predicate evaluateWithObject:self];
}
這里就不給大家驗證了灶似,大家感興趣的可以自行驗證列林。
判斷是否是小數(shù)
還是直接看代碼
//判斷是否是小數(shù)
- (BOOL)jj_isFloatNumber;
//判斷是否是小數(shù)
- (BOOL)jj_isFloatNumber
{
NSString *regex = @"^-?([1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*|0?\\.0+|0)$";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
return [predicate evaluateWithObject:self];
}
這里就帶著大家一起驗證下。
//是否是小數(shù)
- (void)isFloatNumber
{
NSString *str = @"12.13";
BOOL result = [str jj_isFloatNumber];
NSLog(@"result = %d", result);
NSString *str1 = @"999";
BOOL result1 = [str1 jj_isFloatNumber];
NSLog(@"result1 = %d", result1);
}
看輸出結(jié)果
2017-12-16 00:51:41.022796+0800 JJNSStringTool[2221:55765] result = 1
2017-12-16 00:51:41.023191+0800 JJNSStringTool[2221:55765] result1 = 0
可以酪惭,看見可以很好的識別是否是小數(shù)希痴。
后記
未完,待續(xù)~~~