Hacer que la palabra se toque en un UILabel / UITextView

Lo que me gustaría hacer es crear un componente de contenedor de text que sea capaz de indicar cuál es la palabra más cercana cuando hay un toque (es decir, la palabra "detrás" del punto tocado).

Primero, creé una subclass UILabel y anulé los toquesEnded: withEvent: método para determinar el CGPoint tocado. También escribí un método que calcula el "marco" correspondiente (CGRect) de cada palabra del text usando sizeWithFont: forWidth: lineBreakMode :. Con el CGPoint tocado y este marco, puedo determinar qué palabra se está tocando realmente. Pero el método que calcula el marco solo funciona con text mono-línea.

Entonces, ahora necesito saber qué parte del text está en una línea determinada (es decir, cómo se ha dividido el text), para que pueda calcular el margen izquierdo correcto y el margen superior de cada palabra.

¿Alguna idea de cómo puedo get esto? O quizás tengas una solución más sencilla para lograr esto? Esta publicación lamentablemente no fue muy útil … …

(Hay un enlace a un proyecto de código de ejemplo en su publicación vinculada que contiene algún código de ejemplo útil, pero también le describiré el process aquí).

En resumen, necesitará utilizar Core Text, que es el marco avanzado de event handling text basado en C de Apple que respalda todo el layout de text sofisticado en iOS y OS X.

El código completo va a estar algo involucrado, pero los methods key que usted querrá ver son:

CTFramesetterCreateWithAttributedString (): use esto, junto con una NSAttributedString que obtendrá del text de su label, para crear el fotogtwig

CTFramesetterCreateFrame (): usa esto para get un CTFrameRef para tu text del fotogtwigs anterior. Deberá crear un CGPathRef utilizando los límites de su label para hacer esto.

CTFrameGetLines (), CTFrameGetLineOrigins (): utilícelas para get CTLineRefs correspondientes a las líneas de types y a las coorderadas de los orígenes de la línea, respectivamente, luego use CTLineGetStringIndexForPosition () para encontrar el índice de caracteres en una location táctil.

A continuación, puede utilizar este índice de caracteres (en el framework de la línea) para trabajar hacia atrás y encontrar el carácter / palabra / etc real dentro de su cadena completa.

No olvide que las cuestiones se complican por un par de problemas:

  1. Si usas el dibujo nativo de UILabel, tendrás que tener cuidado de hacer coincidir perfectamente tus métricas de composition, que pueden ser engorrosas ya que la mayoría de los objects (por ejemplo, CTFontRef) no tienen un puente entre sus contrapartes UIKit. La implementación de su propio dibujo puede, a veces, ser más fácil, lo que garantizará la coincidencia de métricas.

  2. Core Text utiliza un sistema de coorderadas invertido con respecto al sistema de dibujo iOS normal. Si obtienes resultados extravagantes, y especialmente si haces tu propio dibujo, esto es algo para echarle un vistazo.

No es la tarea más fácil del mundo, pero está lejos de ser imposible. ¡Buena suerte!

Después de search un poco he escrito un código para esto. El código funcionará para UITextView y UILabel .
Simplemente descargue VSWordDetector.zip, luego descomprímalo y arrastre y suelte la carpeta VSWordDetector en su proyecto.
Hay dos files VSWordDetector.h y VSWordDetector.m
#import VSWordDetector.h en su class ViewController .

 @property (strong, nonatomic) VSWordDetector *wordDetector; 

Nota: Haga que su propiedad no se tome como localmente.

Ahora está listo para usted, solo agréguelo en textViews o Labels

 -(void)viewDidLoad { self.wordDetector = [[VSWordDetector alloc] initWithDelegate:self]; [self.wordDetector addOnView:textView]; [self.wordDetector addOnView:label]; } -(void)wordDetector:(VSWordDetector *)wordDetector detectWord:(NSString *)word { NSLog(@"Detected Word: %@", word); } 

Este método de delegado será de llamada cuando toque sobre la label conectada o textView.

EDITAR: Código de ejemplo para VSWordDetector .

EDICION SUGERIDA: si no desea download el código de muestra, aquí está el código de ambos files. Por favor vea este file esencial VSWordDetector .

Aunque esta es una vieja pregunta, pero pensé que esto podría ser de alguna ayuda.

Dado que aprender el text básico fue enorme, opté por GLTapDemo por German Laullon

Con algunos cambios, esto funciona muy bien para detectar palabras tocadas en UILabel.