Изменение парсера Рэя Вендерлиха, не работающего с UITextView

Я попытался перенести в свой проект парсер из простого журнального учебника Рэя Вендерлиха. Его код парсера находится здесь: как создать простое приложение для журнала с основным текстом

Главный контроллер передает текстовую строку синтаксическому анализатору, который анализирует ее, добавляет атрибуты и затем возвращает строку с атрибутами, используя следующий код в 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, но я не совсем понимаю их и поэтому не знаю, вызывают ли они проблему!


person Giovanni    schedule 17.06.2013    source источник


Ответы (2)


Мне кажется, что вы должны работать в среде до iOS6 - хотя вы можете использовать iOS6 SDK, вы можете работать в симуляторе iOS5. У вас точно есть UITextView, если бы это была iOS6, то setAttributedText: было бы хорошо. Раньше у iOS6 UITextView не было свойства attributedText, поэтому попытка его установить приводила к «неизвестному селектору, отправленному экземпляру».

Если вы обнаружите, что это не так, проверьте вывод консоли. Вероятно, он говорит только о том, что такое неизвестный селектор ...

person Adam Eberbach    schedule 17.06.2013
comment
Это то, что я подумал, я перепроверил, не нахожусь ли я на iOS6. Ive также попытался передать uitextview созданную вручную строку (вместо использования строки, поступающей от парсера) для проверки, и она работает с этим. Я в полной растерянности !! - person Giovanni; 18.06.2013
comment
Итак, что говорит консоль - что такое неизвестный селектор? - person Adam Eberbach; 18.06.2013
comment
См. Снимок экрана, добавленный к исходному вопросу для вывода на консоль. - person Giovanni; 18.06.2013
comment
Просто подумайте - будет ли созданный им парсер создавать настраиваемые атрибуты, которые CoreText может использовать, а UITextView - нет? Я заметил, что в своем пользовательском UIView он добавил #import ‹CoreText / CoreText.h›, но поскольку я использую стандартный UIView, я не добавил функциональность coretext в класс? - person Giovanni; 18.06.2013
comment
Можете ли вы опубликовать изображение консоли, то место, где NSLog выводит текст? Вот где вы можете увидеть, что такое фактический неопознанный селектор. - person Adam Eberbach; 18.06.2013
comment
Снова добавлен к исходному вопросу. спасибо, что продолжаете помогать, эти проблемы съели уже весь мой вечер !!! - person Giovanni; 18.06.2013
comment
ОК - pointSize - это то, чего не хватает. Где в коде вы используете pointSize? - person Adam Eberbach; 18.06.2013
comment
В исходный пост было добавлено еще одно дополнение - на этот раз показывающее создание словаря атрибутов шрифта. Я думаю, что мы находимся в поиске проблемы, потому что в двух строках, относящихся к 'fontRef', xcode автоматически добавил код cfbridging. Я понятия не имел, для чего это были, поэтому я не знаю, верны ли они или нет, но кажется слишком большим совпадением, что именно здесь устанавливается размер точки. - person Giovanni; 18.06.2013
comment
Айв также добавил снимок экрана po attString из консоли, чтобы точно показать, какие атрибуты пытаются передать в TextView. - person Giovanni; 18.06.2013

Целых 3 дня спустя его разобрали !!

Мое решение (спасибо @Adam Eberbach за то, что он указал мне на парсер!) - это довольно серьезная переработка кода парсера, используемого Рэем Вендерлихом. В основном проблема заключалась в том, что я извлекал кодирование 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];

Обратите внимание, что сюда не входят атрибуты цвета и ширины обводки, которые были у Рэя в его оригинале, потому что они не поддерживаются UITextView, а только CoreText. Однако любые другие атрибуты теперь можно установить таким же образом, просто добавив еще одно регулярное выражение и еще один add: Attribute.

В общем, теперь у меня есть очень простой способ преобразовать длинный файл .txt в текст с атрибутами, просто добавив пару тегов в текст, где я хочу изменить формат. Моя благодарность Рэю и Алану!

person Giovanni    schedule 18.06.2013
comment
Этот сайт бесценен для изучения деталей, которые я никогда не смог бы понять самостоятельно, но нет ничего лучше, чем выяснить, почему что-то не работает, и исправить это самостоятельно! - person Giovanni; 19.06.2013