1

我试图将 Ray Wenderlich 的简单杂志教程中的解析器提升到我的项目中。他的解析器代码在这里: 如何使用核心文本创建一个简单的杂志应用程序

主控制器将文本字符串传递给解析器,解析器对其进行剖析,添加属性,然后返回属性字符串,在 viewDidLoad 中使用以下代码:

 - (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *path = [[NSBundle mainBundle] pathForResource:@"zombies" ofType:@"txt"];
    NSString* text = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
MarkupParser* p = [[[MarkupParser alloc] init] autorelease];
NSAttributedString* attString = [p attrStringFromMarkup: text];
[(CTView *)[self view] setAttString:attString withImages: p.images];
[(CTView *)[self view] buildFrames];
}

当我使用 Ios6 时,我认为从解析器传回的属性字符串可以简单地添加到 UITextView 而不必乱用 CoreText。考虑到这一点,我将上面的代码更改为以下内容:

    - (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *path = [[NSBundle mainBundle] pathForResource:@"zombies" ofType:@"txt"];
    NSString* text = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
    MarkupParser* p = [[[MarkupParser alloc] init] autorelease];
    NSAttributedString* attString = [p attrStringFromMarkup: text];

    UITextView *view = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];

    view.attributedText = attString;
    [self.view addSubview:view];
}

但是,这现在会在将 view.attributedText 设置为 attString 的行上产生一个错误,指出“发送到实例的未知选择器”。我确定从解析器返回的属性字符串是罪魁祸首,但我一生都无法弄清楚为什么!有什么想法吗?


这是运行时控制台的屏幕截图:

在此处输入图像描述

在此处输入图像描述


下一张图片是导致问题的 AttributedString 中名为 attString 的详细信息的屏幕截图

在此处输入图像描述

最后,代码的以下部分是解析器设置其属性的地方,这可能会导致上面调试器中显示的 pointSize 错误。

 CTFontRef fontRef = CTFontCreateWithName((CFStringRef)CFBridgingRetain(self.font),
                                             24.0f, NULL);

 //apply the current text style
 NSDictionary* attrs = [NSDictionary dictionaryWithObjectsAndKeys:
                       (id)self.color.CGColor, kCTForegroundColorAttributeName,
                       (id)CFBridgingRelease(fontRef), kCTFontAttributeName,
                       (id)self.strokeColor.CGColor, (NSString *) kCTStrokeColorAttributeName,
                       (id)[NSNumber numberWithFloat: self.strokeWidth], (NSString *)kCTStrokeWidthAttributeName,
                       nil];

 [aString appendAttributedString:[[NSAttributedString alloc] initWithString:[parts objectAtIndex:0] attributes:attrs] ];

上面的“桥接”命令是 Xcode 自动添加的,我知道它与 ARC 有关,但我不太了解它们,所以不知道这些是否导致问题!

4

2 回答 2

2

整整 3 天后,它的排序!

我的解决方案(感谢@Adam Eberbach 将我指向解析器!)是对 Ray Wenderlich 使用的解析器代码进行了相当大的改造。基本上问题是我从他的示例中提取 CoreText 编码并尝试在 UITextView 属性字符串中使用这些属性 - 所以 UITextView 不理解传递给它的内容。

通过用基本的 NS 属性而不是 CG 属性替换他的解析器(从而改变了他的大部分代码!),UITextView 就能够理解传递给它的内容。我能够保留他创建的相同正则表达式,这是天赐之物,因为尽我所能,我无法理解所有这些符号的含义!

我对原始帖子中最后一段代码的替换代码如下:

    for (NSTextCheckingResult* b in chunks) {
    NSArray* parts = [[markup substringWithRange:b.range]
                      componentsSeparatedByString:@"<"]; //1

    NSMutableAttributedString *temp = [[NSMutableAttributedString alloc] initWithString:[parts objectAtIndex:0]];
    [temp addAttribute:NSFontAttributeName value:[UIFont fontWithName:self.font size:20] range:NSMakeRange(0, [temp length])];
    [temp addAttribute:NSForegroundColorAttributeName value:self.color range:NSMakeRange(0, [temp length])];

    [aString appendAttributedString:temp];

请注意,这不包括 Ray 在其原始文件中的笔触颜色和宽度属性,因为 UITextView 不支持这些属性,只有 CoreText 支持。但是,现在可以以相同的方式设置任何其他属性,只需简单地添加另一个正则表达式和另一个 add:Attribute。

总而言之,我现在有一种非常简单的方法,只需在我希望更改格式的文本中添加几个标签,即可将长 .txt 文件转换为属性文本。我感谢雷和艾伦!

于 2013-06-18T14:42:12.447 回答
2

在我看来,您必须在 iOS6 之前的环境中运行 - 虽然您可能正在使用 iOS6 SDK,但您可能在 iOS5 模拟器中运行。你肯定有一个UITextView,如果是 iOS6 那就没问题setAttributedText:了。在 iOS6UITextView之前没有该attributedText属性,因此尝试设置它会导致“发送到实例的未知选择器”。

如果您发现情况并非如此,请检查您的控制台输出。它可能只是说未知选择器是什么......

于 2013-06-17T23:26:25.970 回答