Domanda

Ho un po 'in un gestore di contatto che risponde ad un rubinetto su una vista che ho disegnato un testo attribuito a. Attraverso questo, devo al punto in cui ho un CTRunRef (e la linea associata) come così come il numero di glifi in quel periodo.

Quello che non sono in grado di capire con facilità, è come posso prendere quel percorso di glifi e, data la mia stringa attribuito, la mappa fuori per caratteri della stringa.

In particolare, il problema è che vorrei sapere quale parola l'utente bussò nella vista, in modo da poter elaborare o meno di questa parola è un URL e il fuoco fuori di un metodo delegato personalizzato in modo da poter aprire una vista web con esso . Ho tutti i possibili stringhe, solo che non so come mappare in cui l'utente sfruttato per una particolare stringa.

Qualsiasi aiuto sarebbe molto apprezzato.

Aggiorna : In realtà ho andato e fatto in un modo diverso, su suggerimento di un'altra persona fuori di StackOverflow. Fondamentalmente quello che ho fatto è quello di impostare un attributo personalizzato, @"MyAppLinkAddress" con il valore del URL ho trovato quando mi è stato la conversione della stringa in una stringa attribuito. Questo avviene prima di disegnare la stringa. Pertanto, quando si verifica un evento di rubinetto, ho solo controllare se esiste l'attributo, e in caso affermativo, chiamo il mio metodo delegato, se non, semplicemente ignorarlo. Si sta lavorando come mi piacerebbe adesso, ma ho intenzione di lasciare questa questione aperta per un paio di giorni, se qualcuno può trovare una risposta, io accetto volentieri se una soluzione di lavoro in modo tale che alcuni altri può essere in grado di trovare queste informazioni utili ad un certo punto in futuro.

È stato utile?

Soluzione

Quindi, come ho detto nel l'aggiornamento, ho deciso di andare un percorso diverso. Invece ho avuto l'idea di utilizzare un attributo personalizzato nella stringa attribuito per specificare il mio link, dal momento che ho avuto al momento della creazione in ogni caso. Così ho fatto. Poi, nel mio gestore tocco, quando una corsa viene toccato, mi controllare se quella corsa ha quell'attributo, e in tal caso, chiamare il mio delegato con esso. Da lì Sono felicemente il caricamento di una WebView con questo URL.

Modifica : Qui di seguito sono frammenti di codice che spiegano quello che ho fatto in questa risposta. Godetevi.

// 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];

poi ...

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

Altri suggerimenti

Dopo aver trovato la linea sfruttato, si può chiedere per l'indice nella stringa chiamando CTLineGetStringIndexForPosition(). Non c'è alcuna necessità per accedere ai singoli percorsi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top