搜索
在一个字符串中搜索子字符串
最灵活的方法
- (NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)searchRange locale:(NSLocale *)locale
格式化字符串
- 3个方法
-initWithFormat:
-initWithFormat:arguments:
+stringWithFormat:
整数
可以同时工作在32位和64位的
uint64_t p = 2305843009213693951;
NSString *s = [NSString stringWithFormat:@”The ninth Mersenne prime is %llu”, (unsigned long long) p];
// “The ninth Mersenne prime is 2305843009213693951”
Modifier | d, i | o, u, x, X |
---|---|---|
hh | signed char | unsigned char |
h | short | unsigned short |
(none) | int | unsigned int |
l(ell) | long | unsigned long |
j | intmax_t | uintmax_t |
t | ptrdiff_t | |
z | size_t |
转换规则
int m = -150004021;
uint n = 150004021U;
NSString *s = [NSString stringWithFormat:@”d:%d i:%i o:%o u:%u x:%x X:%X”, m, m, n, n, n, n];
// “d:-150004021 i:-150004021 o:1074160465 u:150004021 x:8f0e135 X:8F0E135”
//o是八进制
设置最小字段宽度和最小数字位数
int m = 42;
NSString *s = [NSString stringWithFormat:@”‘%4d’ ‘%-4d’ ‘%+4d’ ‘%4.3d’ ‘%04d’”, m, m, m, m, m];
// “[ 42] [42 ] [ +42] [ 042] [0042]”
m = -42;
NSString *s = [NSString stringWithFormat:@”‘%4d’ ‘%-4d’ ‘%+4d’ ‘%4.3d’ ‘%04d’”, m, m, m, m, m];
// “[ -42] [-42 ] [ -42] [-042] [-042]”
%p可打印指针,和%#x不同的是它可以同时在32位和64位执行
浮点数
使用%f和%g
double v[5] = {12345, 12, 0.12, 0.12345678901234, 0.0000012345678901234};
NSString *s = [NSString stringWithFormat:@”%g %g %g %g %g”, v[0], v[1], v[2], v[3], v[4]];
// “12345 12 0.12 0.123457 1.23457e-06”
NSString *s = [NSString stringWithFormat:@”%f %f %f %f %f”, v[0], v[1], v[2], v[3], v[4]];
// “12345.000000 12.000000 0.120000 0.123457 0.000001”
多行文字
使用\n来
NSString *limerick = @”A lively young damsel named Menzies\n”
@”Inquired: «Do you know what this thenzies?»\n”
@”Her aunt, with a gasp,\n”
@”Replied: “It’s a wasp,\n”
@”And you’re holding the end where the stenzies.\n”;
等价写法
NSString *limerick = @”A lively young damsel named Menzies\nInquired: «Do you know what this thenzies?»\nHer aunt, with a gasp,\nReplied: “It’s a wasp,\nAnd you’re holding the end where the stenzies.\n”;
更简洁的方法
NSString * string = @”The man “ @”who knows everything “ @”learns nothing” @”.”;
替换字符串
NSMutableString的四个方法
-deleteCharactersInRange:
-insertString:atIndex:
-replaceCharactersInRange:withString:
-replaceOccurrencesOfString:withString:options:range:
NSString的方法
-stringByReplacingOccurrencesOfString:withString:
-stringByReplacingOccurrencesOfString:withString:options:range:
-stringByReplacingCharactersInRange:withString:
NSMutableString不会创建新字符串,性能会好点
NSMutableString *string; // 假设我们已经有了一个名为 string 的字符串
// 现在要去掉它的一个前缀,做法如下:
NSString *prefix = @”WeDon’tWantThisPrefix”
NSRange r = [string rangeOfString:prefix options:NSAnchoredSearch range:NSMakeRange(0, string.length) locale:nil];
if (r.location != NSNotFound) {
[string deleteCharactersInRange:r];
}
连接字符串
1 | NSArray *names = @["Hildr", @"Heidrun", @"Gerd", @"Guðrún", @"Freya", @"Nanna", @"Siv", @"Skaði", @"Gróa"]; |
字符串解析
正则表达式
1 |
|
将字符串分解成数组,使用componentsSeparatedByString:这个方法,或者enumerateSubstringsInRange:options:usingBlock:。如果是按照行来进行分解可以使用option这个参数传NSStringEnumerationByLines
1 |
|
扫描
NSScanner
NSScanner *scanner = [NSScanner scannerWithString:string];
//默认情况下,扫描器会跳过所有空格符和换行符。但这里我们只希望跳过空格符
scanner.charactersToBeSkipped = [NSCharacterSet whitespaceCharacterSet];
//定义一个十六进制字符集
NSCharacterSet *hexadecimalCharacterSet =
[NSCharacterSet characterSetWithCharactersInString:@”0123456789abcdefABCDEF”];
NSMutableDictionary *result = [NSMutableDictionary dictionary];
while (!scanner.isAtEnd) {
NSString *key = nil; NSString *value = nil; NSCharacterSet *letters = [NSCharacterSet letterCharacterSet]; BOOL didScan = [scanner scanCharactersFromSet:letters intoString:&key] && [scanner scanString:@"=" intoString:NULL] && [scanner scanString:@"#" intoString:NULL] && [scanner scanCharactersFromSet:hexadecimalCharacterSet intoString:&value] && value.length == 6; result[key] = value; [scanner scanCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:NULL]; // 继续扫描下一行
}
return result;
解析器
设计一个能够用(100,0,255)或者#ff0000这样的字符来定义颜色的方法。
- (NSDictionary *)parse:(NSString *)string error:(NSError **)error
{
self.scanner = [NSScanner scannerWithString:string]; self.scanner.charactersToBeSkipped = [NSCharacterSet whitespaceCharacterSet]; NSMutableDictionary *result = [NSMutableDictionary dictionary]; NSCharacterSet *letters = [NSCharacterSet letterCharacterSet] while (!self.scanner.isAtEnd) { NSString *key = nil; UIColor *value = nil; BOOL didScan = [self.scanner scanCharactersFromSet:letters intoString:&key] && [self.scanner scanString:@"=" intoString:NULL] && [self scanColor:&value]; result[key] = value; [self.scanner scanCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:NULL]; // 继续扫描下一行 }
}
- (BOOL)scanColor:(UIColor **)out
{
return [self scanHexColorIntoColor:out] || [self scanTupleColorIntoColor:out];
}
//扫描设置#ff0000这样的
- (BOOL)scanHexColorIntoColor:(UIColor **)out
{
NSCharacterSet *hexadecimalCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789abcdefABCDEF"]; NSString *colorString = NULL; if ([self.scanner scanString:@"#" intoString:NULL] && [self.scanner scanCharactersFromSet:hexadecimalCharacterSet intoString:&colorString] && colorString.length == 6) { *out = [UIColor colorWithHexString:colorString]; return YES; } return NO;
}
- (BOOL)scanTupleColorIntoColor:(UIColor **)out
{
NSInteger red, green, blue = 0; BOOL didScan = [self.scanner scanString:@"(" intoString:NULL] && [self.scanner scanInteger:&red] && [self.scanner scanString:@"," intoString:NULL] && [self.scanner scanInteger:&green] && [self.scanner scanString:@"," intoString:NULL] && [self.scanner scanInteger:&blue] && [self.scanner scanString:@")" intoString:NULL]; if (didScan) { *out = [UIColor colorWithRed:(CGFloat)red/255. green:(CGFloat)green/255. blue:(CGFloat)blue/255. alpha:1]; return YES; } else { return NO; }
}
符号化处理
先进星扫描,使用NSScanner来解析这个表达式
1 |
|
1 |
|
进行语法解析,需要语法分析库描述我们的语言。下面代码就是为那个布局约束语言写的解析语法,用的扩展的巴科斯范式EBNF写法:
1 |
|
还有很多Objective-C的语法解析,更多的可以在CocoaPods上找到:http://cocoapods.org/?q=parse。比较好的就是CoreParse,地址:https://github.com/beelsebob/CoreParse,但是需要使用它支持的语法。下面就是CoreParse支持的格式:
1 | NSString* grammarString = [@[ |
一个规则匹配后解析器就找到同样名称的类
1 |
|
完整的解析器代码在:https://github.com/objcio/issue-9-string-parsing。里面有个解析类可以用来解析复杂的布局约束,如下:
1 |
|
可以得到如下结果,方便转换成NSLayoutConstraint对象
1 |
|
字符串的渲染
UILabel
- label默认显示一行,如果设置numberOfLines为大于1的话可以显示指定行数,如果设置为0,则多少行都显示
- attributedText属性可以显示富文本
- label的font,textColor,textAlignment,shadowColor和shadowOffset属性可以改变外观。
- 改变程序内所有Label的风格,可以使用[UILabel appearance]方法
UITextField
- text field只限于单行
- UITextfield实现了UITextInputTraits协议,这个协议需要指定键盘外观和操作等细节。比如显示什么键盘和返回按键响应等
- 可以通过设置左右辅助视图,或者设置背景来自定义输入框风格了。
UITextView
- 相比较UITextField,它能够处理多行文本
- 可以使用定制Text Kit,官方文档:https://developer.apple.com/Library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html
- 可以为layout manager,text container或text storage自定义行为或替换自定义子类。
- 在iOS7之前是基于WebKit的功能少,之后会有很多不同具体可以参考这两篇文章:Peter的http://petersteinberger.com/blog/2014/fixing-uitextview-on-ios-7/,Brent的http://inessential.com/2014/01/07/uitextview_the_solution
TableView中显示动态文本
Table view的Delegate有个方法用来计算高度:tableView:heightForRowAtIndexPath:。自定义一个UITableViewCell的子类
1 |
|
计算真实高度需要使用boundingRectWithSize:options:context: 这个方法
1 |
|
使用Text Kit和NSAttributedString进行布局
先设置attributes
1 |
|
这里字体为BodoniSvtyTwoITCTT,如果需要查看更多字体可以使用 +[UIFont familyNames]这个方法。为了得到字体的名字,可以使用 +[UIFont fontNamesForFamilyName:]。接下来创建段落的属性
1 | NSMutableDictionary *bodyAttributes = [body1stAttributes mutableCopy]; |
装饰段落风格,使用装饰字体将文本居中对齐,装饰字符的前后加上空白段落
1 |
|
显示数字表格table,表格布局示例
1 |
|
显示列表的属性设置如下
1 |
|
字符串本地化
- 使用NSLocalizedString,可查看文章《字符串本地化》:(中文)http://objccn.io/issue-9-3/ (英文)http://www.objc.io/issue-9/string-localization.html