Tengo un código en una vista que dibuja texto atribuido utilizando CoreText. En esto, estoy buscando URL y haciéndolas azules. La idea es no incluir todos los gastos generales de un UIWebView
solo para obtener enlaces clicables. Una vez que un usuario toca en ese enlace (no en toda la celda de la vista de tabla), deseo activar un método delegado que luego se usará para presentar una vista modal que contiene una vista web que va a esa url.Uso de CoreText y toques para crear una acción seleccionable
Estoy guardando la ruta y la cadena en sí misma como variables de instancia de la vista, y el código de dibujo ocurre en -drawRect:
(lo dejé para abreviar).
Sin embargo, mi controlador táctil, si bien está incompleto, no imprime lo que esperaba. Es a continuación:
- (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
}
}
}
}
}
no es el código más bonito en este momento, todavía estoy tratando de hacer que funcione solo, por lo que valga la calidad del código.
El problema que tengo es que cuando toco fuera del enlace, lo que espero que suceda, sucede: Nada se dispara.
Sin embargo, yo esperaría a "Tapped line"
se imprimen si tocar en la misma línea el enlace está activado, lo cual no sucede, y yo esperaría tanto "Tapped line"
y "Tapped run"
que se imprimen si hago tapping en la URL.
No estoy seguro de dónde llevar esto más allá, los recursos que he examinado para resolver este problema son específicos de Cocoa (que es casi completamente inaplicable) o carecen de información sobre este caso específico.
Con mucho gusto le mostraré los punteros a la documentación que detalla cómo detectar correctamente si ocurrió un toque dentro de los límites de un texto central que dibuja el código, pero en este punto, solo quiero resolver este problema, por lo que cualquier La ayuda sería muy apreciada.
ACTUALIZACIÓN: He reducido mi problema a un problema de coordinación. He dado la vuelta a las coordenadas (y no como se muestra arriba) y el problema que tengo es que toca registrarme como era de esperar, pero el espacio de coordenadas está volteado, y parece que no puedo voltearlo.
¿Ha tenido en cuenta el hecho de que CoreText utiliza un sistema de coordenadas volteado? En este momento me parece que estás comparando cosas en dos sistemas de coordenadas diferentes. – Jacques
Además, es una mala idea recrear el fotocomponedor en cada toque así. Crear un conjunto de marcos es muy costoso, por lo que debe almacenarlo en la memoria caché al momento de dibujar o configurar el texto. – Jacques
Mi metodología de desarrollo es simple: 1) Hacer que funcione; 2) Hacerlo bien; 3) Hazlo rápido/limpio. Vamos a tratar con el # 2 cuando tengamos el # 1 en funcionamiento :) También con respecto al sistema de coordenadas, sí me doy cuenta de eso, y por un tiempo no lo estaba manejando.Ahora, en el código, después de consultar con un colega, él me puso en línea con esto, y al menos ahora está detectando los grifos en las líneas, pero no las ejecuciones. Todavía estoy tratando de resolverlo. – jer