ho qualche codice in una vista che richiama un testo attribuito utilizzando CoreText. In questo, sto cercando gli URL e li faccio diventare blu. L'idea è di non portare tutto il sovraccarico di un UIWebView
solo per ottenere link cliccabili. Una volta che un utente tocca quel collegamento (non l'intera cella di visualizzazione tabella), voglio attivare un metodo delegato che verrà quindi utilizzato per presentare una vista modale che contiene una vista Web che va a quell'URL.Utilizzando CoreText e tocca per creare un'azione cliccabile
Sto salvando il percorso e la stringa stessa come variabili di istanza della vista e il codice di disegno si verifica in -drawRect:
(l'ho lasciato per brevità).
mio gestore tocco tuttavia, pur incompleta, non è stampa quello che mi aspettavo che. Si tratta qui di seguito:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
CGContextRef context = UIGraphicsGetCurrentContext();
NSLog(@"attribString = %@", self.attribString);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self.attribString);
CTFrameRef ctframe = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, self.attribString.length), attribPath, NULL);
CFArrayRef lines = CTFrameGetLines(ctframe);
for(CFIndex i = 0; i < CFArrayGetCount(lines); i++)
{
CTLineRef line = CFArrayGetValueAtIndex(lines, i);
CGRect lineBounds = CTLineGetImageBounds(line, context);
// Check if tap was on our line
if(CGRectContainsPoint(lineBounds, point))
{
NSLog(@"Tapped line");
CFArrayRef runs = CTLineGetGlyphRuns(line);
for(CFIndex j = 0; j < CFArrayGetCount(runs); j++)
{
CTRunRef run = CFArrayGetValueAtIndex(runs, j);
CFRange urlStringRange = CTRunGetStringRange(run);
CGRect runBounds = CTRunGetImageBounds(run, context, urlStringRange);
if(CGRectContainsPoint(runBounds, point))
{
NSLog(@"Tapped run");
CFIndex* buffer = malloc(sizeof(CFIndex) * urlStringRange.length);
CTRunGetStringIndices(run, urlStringRange, buffer);
// TODO: Map the glyph indices to indexes in the string & Fire the delegate
}
}
}
}
}
non è il codice più bella in questo momento, sto ancora cercando di fare solo il lavoro, in modo da perdonare la qualità del codice.
Il problema che sto avendo è che quando si tocca il link di fuori, quello che mi aspetto sarebbe accaduto, accade: Nulla viene licenziato.
Tuttavia, mi aspetterei "Tapped line"
per ottenere stampati se si tocca la stessa linea il collegamento è attivo, cosa che non accade, e mi aspetto sia "Tapped line"
e "Tapped run"
per ottenere stampati se si tocca sull'URL.
Non sono sicuro di dove andare oltre, le risorse che ho visto per la risoluzione di questo problema sono specifiche del cacao (che è quasi completamente inapplicabile) o mancano di informazioni su questo caso specifico.
Prenderò volentieri un suggerimento alla documentazione che descrive dettagliatamente come rilevare correttamente se un tocco si è verificato entro i limiti di un testo di base che si disegna sul codice, ma a questo punto, voglio solo risolvere questo problema, quindi qualsiasi l'aiuto sarebbe molto apprezzato.
UPDATE: Ho ristretto il mio problema a un problema di coordinate. Ho capovolto le coordinate (e non come indicato sopra) e il problema che sto ricevendo è che tocchi registrarsi come mi aspetto, ma lo spazio di coordinate è capovolto, e io non riesco a capovolgere indietro.
Avete preso in considerazione il fatto che CoreText utilizza un sistema di coordinate capovolto? In questo momento mi sembra che tu stia confrontando le cose in due diversi sistemi di coordinate. – Jacques
Inoltre, è una cattiva idea ricreare il framesetter su ogni tocco del genere. La creazione di un frame-set è molto costosa, quindi è consigliabile memorizzarla nella cache quando si inizia a disegnare o impostare il testo. – Jacques
La mia metodologia di sviluppo è semplicemente: 1) Fallo funzionare; 2) fallo bene; 3) Renderlo veloce/pulito. Affrontiamo il n. 2 quando otteniamo # 1 in corso :) Anche per quanto riguarda il sistema di coordinate, sì, me ne rendo conto e per un po 'non lo stavo gestendo.Nel codice ora, dopo essermi consultato con un collega, mi ha impostato direttamente su questo, e ora sta rilevando almeno i tocchi sulle linee, ma non le esecuzioni. Sto ancora cercando di capirlo. – jer