CoreText отображающие символы - PullRequest
       1

CoreText отображающие символы

9 голосов
/ 29 сентября 2010

У меня есть обработчик касания, который реагирует на нажатие на представление, в котором я нарисовал какой-то атрибутивный текст. Благодаря этому я дошел до точки, где у меня есть CTRunRef (и связанная строка), а также количество глифов в этом цикле.

Что я не могу понять, так это то, как я могу взять этот цикл глифов и, учитывая мою приписанную строку, сопоставить ее с символамив строке.

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

Любая помощь будет принята с благодарностью.

ОБНОВЛЕНИЕ : На самом деле я пошел и сделал это по-другому, по предложению другого человека из стека overflow.По сути, я установил пользовательский атрибут @"MyAppLinkAddress" со значением URL-адреса, который я нашел, когда преобразовывал строку в строку с атрибутами.Это происходит до того, как я нарисую строку.Поэтому, когда происходит событие касания, я просто проверяю, существует ли этот атрибут, и если да, вызываю мой метод делегата, если нет, просто игнорирую его.Сейчас это работает так, как мне хотелось бы, но я собираюсь оставить этот вопрос открытым еще на несколько дней, если кто-то может придумать ответ, я с радостью приму его, если это рабочее решение, так что некоторые другиевозможно, эта информация окажется полезной в будущем.

Ответы [ 2 ]

7 голосов
/ 01 октября 2010

Итак, как я упоминал в обновлении, я решил пойти другим путем. Вместо этого у меня появилась идея использовать пользовательский атрибут в строке атрибута для указания моей ссылки, так как она была у меня во время создания. Я так и сделал. Затем в моем обработчике касания, когда выполняется запуск, я проверяю, имеет ли этот запуск этот атрибут, и если да, то вызывает моего делегата с ним. Оттуда я с удовольствием загружаю веб-просмотр с этим URL.

РЕДАКТИРОВАТЬ : Ниже приведены фрагменты кода, объясняющие, что я сделал в этом ответе. Наслаждайтесь.

// When creating the attribute on your text store. Assumes you have the URL already. 
// Filled in for convenience
NSRange urlRange = [tmpString rangeOfString:@"http://www.foo.com/"];
[self.textStore addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)[UIColor blueColor].CGColor range:urlRange];
[self.textStore addAttribute:@"CustomLinkAddress" value:urlString range:urlRange];

тогда ...

// Touch handling code — Uses gesture recognizers, not old school touch handling.
// This is just a dump of code actually in use, read through it, ask questions if you
// don't understand it. I'll do my best to put it in context.
- (void)receivedTap:(UITapGestureRecognizer*)tapRecognizer
{
        CGPoint point = [tapRecognizer locationInView:self];

        if(CGRectContainsPoint(textRect, point))
        {
                CGContextRef context = UIGraphicsGetCurrentContext();

                point.y = CGRectGetHeight(self.contentView.bounds) - kCellNameLabelHeight - point.y;

                CFArrayRef lines = CTFrameGetLines(ctframe);
                CFIndex lineCount = CFArrayGetCount(lines);
                CGPoint origins[lineCount];
                CTFrameGetLineOrigins(ctframe, CFRangeMake(0, 0), origins);
                for(CFIndex idx = 0; idx < lineCount; idx++)
                {
                        CTLineRef line = CFArrayGetValueAtIndex(lines, idx);
                        CGRect lineBounds = CTLineGetImageBounds(line, context);
                        lineBounds.origin.y += origins[idx].y;

                        if(CGRectContainsPoint(lineBounds, point))
                        {
                                CFArrayRef runs = CTLineGetGlyphRuns(line);
                                for(CFIndex j = 0; j < CFArrayGetCount(runs); j++)
                                {
                                        CTRunRef run = CFArrayGetValueAtIndex(runs, j);
                                        NSDictionary* attributes = (NSDictionary*)CTRunGetAttributes(run);
                                        NSString* urlString = [attributes objectForKey:@"CustomLinkAddress"];
                                        if(urlString && ![urlString isEqualToString:@""])
                                        {
                                                [self.delegate didReceiveURL:[NSURL URLWithString:urlString]];
                                                UIGraphicsPopContext();
                                                return;
                                        }
                                }
                        }
                }
                UIGraphicsPopContext();
        }
}
3 голосов
/ 18 мая 2012

После того, как вы найдете повернутую строку, вы можете запросить индекс в строке, вызвав CTLineGetStringIndexForPosition().Нет необходимости получать доступ к отдельным прогонам.

...