reg*_*633 10 cocoa attributes objective-c nsattributedstring
我需要在NSTextView中为所选文本添加自定义属性.所以我可以通过获取选择的属性字符串,向其添加自定义属性,然后用我的新属性字符串替换选择来实现.
所以现在我将文本视图的属性字符串作为NSData并将其写入文件.稍后,当我打开该文件并将其恢复到文本视图时,我的自定义属性消失了!在为我的自定义属性计算出整个方案后,我发现不会为您保存自定义属性.请查看以下重要提示:http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/AttributedStrings/Tasks/RTFAndAttrStrings.html
所以我不知道如何使用此自定义属性保存和恢复我的文档.有帮助吗?
Rob*_*ger 16
保存的正常方法NSAttributedString是使用RTF,而RTF数据是生成-dataFromRange:documentAttributes:error:方法的内容NSAttributedString.
但是,RTF格式不支持自定义属性.相反,您应该使用NSCoding协议来归档您的属性字符串,这将保留自定义属性:
//asssume attributedString is your NSAttributedString
//encode the string as NSData
NSData* stringData = [NSKeyedArchiver archivedDataWithRootObject:attributedString];
[stringData writeToFile:pathToFile atomically:YES];
//read the data back in and decode the string
NSData* newStringData = [NSData dataWithContentsOfFile:pathToFile];
NSAttributedString* newString = [NSKeyedUnarchiver unarchiveObjectWithData:newStringData];
Run Code Online (Sandbox Code Playgroud)
小智 6
有一种方法可以使用Cocoa将自定义属性保存到RTF.它依赖于RTF是一种文本格式的事实,因此即使您不了解RTF的所有规则并且没有自定义RTF读取器/写入器,也可以将其作为字符串进行操作.我在下面概述的程序在写入和阅读时对RTF进行了后处理,并且我亲自使用了这种技术.有一点需要注意的是,插入RTF的文本只使用7位ASCII,没有未转义的控制字符,包括"\ {}".
以下是对数据进行编码的方法:
NSData *GetRtfFromAttributedString(NSAttributedString *text)
{
NSData *rtfData = nil;
NSMutableString *rtfString = nil;
NSString *customData = nil, *encodedData = nil;
NSRange range;
NSUInteger dataLocation;
// Convert the attributed string to RTF
if ((rtfData = [text RTFFromRange:NSMakeRange(0, [text length]) documentAttributes:nil]) == nil)
return(nil);
// Find and encode your custom attributes here. In this example the data is a string and there's at most one of them
if ((customData = [text attribute:@"MyCustomData" atIndex:0 effectiveRange:&range]) == nil)
return(rtfData); // No custom data, return RTF as is
dataLocation = range.location;
// Get a string representation of the RTF
rtfString = [[NSMutableString alloc] initWithData:rtfData encoding:NSASCIIStringEncoding];
// Find the anchor where we'll put our data, namely just before the first paragraph property reset
range = [rtfString rangeOfString:@"\\pard" options:NSLiteralSearch];
if (range.location == NSNotFound)
{
NSLog(@"Custom data dropped; RTF has no paragraph properties");
[rtfString release];
return(rtfData);
}
// Insert the starred group containing the custom data and its location
encodedData = [NSString stringWithFormat:@"{\\*\\my_custom_keyword %d,%@}\n", dataLocation, customData];
[rtfString insertString:encodedData atIndex:range.location];
// Convert the amended RTF back to a data object
rtfData = [rtfString dataUsingEncoding:NSASCIIStringEncoding];
[rtfString release];
return(rtfData);
}
Run Code Online (Sandbox Code Playgroud)
这种技术有效,因为所有兼容的RTF阅读器都会忽略其无法识别其关键字的"已加星标的群组".因此,您需要确保您的控制字不会被任何其他读者识别,因此请使用可能唯一的内容,例如您公司的前缀或产品名称.如果您的数据很复杂,或者是二进制数据,或者可能包含您不想转义的非法RTF字符,请在base64中对其进行编码.请务必在关键字后面留一个空格.
同样,在读取RTF时,您将搜索控制字,提取数据并恢复属性.此例程将属性字符串和从中创建的RTF作为参数.
void RestoreCustomAttributes(NSMutableAttributedString *text, NSData *rtfData)
{
NSString *rtfString = [[NSString alloc] initWithData:rtfData encoding:NSASCIIStringEncoding];
NSArray *components = nil;
NSRange range, endRange;
// Find the custom data and its end
range = [rtfString rangeOfString:@"{\\*\\my_custom_keyword " options:NSLiteralSearch];
if (range.location == NSNotFound)
{
[rtfString release];
return;
}
range.location += range.length;
endRange = [rtfString rangeOfString:@"}" options:NSLiteralSearch
range:NSMakeRange(range.location, [rtfString length] - endRange.location)];
if (endRange.location == NSNotFound)
{
[rtfString release];
return;
}
// Get the location and the string data, which are separated by a comma
range.length = endRange.location - range.location;
components = [[rtfString substringWithRange:range] componentsSeparatedByString:@","];
[rtfString release];
// Assign the custom data back to the attributed string. You should do range checking here (omitted for clarity)
[text addAttribute:@"MyCustomData" value:[components objectAtIndex:1]
range:NSMakeRange([[components objectAtIndex:0] integerValue], 1)];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7133 次 |
| 最近记录: |