改变Ray Wenderlich的Parser不使用UITextView

时间:2013-06-17 23:14:14

标签: iphone xcode nsattributedstring

我试图将Ray Wenderlich的简单杂志教程中的解析器提升到我的项目中。他的解析器代码在这里: how to create a simple magazine app with core text

主控制器将文本字符串传递给解析器,解析器将解析它,添加属性然后返回属性字符串,使用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。我确定从解析器返回的属性字符串是责备,但不能解释为什么我的生活!那里有什么想法吗?


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

enter image description here

enter image description here


下一张图片是AttributedString中名为attString的细节的屏幕截图,它引起了问题

enter image description here

最后,代码的以下部分是解析器获取其属性集的位置,并且可能导致上面调试器中显示的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有关,但我真的不了解它们,所以不知道这些是否会导致问题!

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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文件转换为属性文本,只需在文本中添加几个我希望格式更改的标记即可。我对雷和艾伦表示感谢!