2010-09-29 3 views
9

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

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

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

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

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

ответ

7

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

EDIT: Ниже приведены фрагменты кода, объясняющие, что я сделал в этом ответе. Наслаждаться.

// 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(); 
     } 
} 
+0

Вам не нужно вызывать 'UIGraphicsPopContext()' здесь. Вы просто получаете контекст, а не выдвигаете новый. – mohsenr

3

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

Смежные вопросы