2010-12-07 9 views
6

Tengo UILabel que tiene algunos nombres de texto y 2 meses como "En el mes de enero y julio, el brillo del sol será el máximo" Subestimé UILabel y agregué el evento táctil a él . Ahora quiero poner la palabra debajo del texto donde el usuario tocó y averiguar si el usuario tocó enero/julio o no. ¿Es posible?UILabel toca y obtén el texto donde tocó

Respuesta

3

Creo que encontrará lo que está buscando en la documentación para UITextInputProtocol.

Para obtener más información de alto nivel, consulte el Text, Web and Editing Guide de Apple, específicamente en la sección titulada "Un recorrido guiado de una implementación UITextInput". Discute cómo puede crear posiciones indexadas en el texto y pregunta qué posición de texto han aterrizado más cerca.

Apple hace referencia a una muestra proyectada llamada SimpleTextInput, pero parece que no puedo encontrarla. Seguiré buscando.

+0

¿Tiene algún ejemplo o tutorial sobre cómo usarlo? – Satyam

+0

hey, Apple mencionó el código de muestra - tratando de ver si puedo encontrarlo ahora. –

+0

Ahora (2011-01-19) está disponible aquí: http://developer.apple.com/library/ios/#samplecode/SimpleTextInput/Introduction/Intro.html – Stephan

0

He manejado este problema al colocar UIViews transaparent en la parte superior de UILabel que estaban conectadas para manejar eventos táctiles. Puede ajustar la posición y el tamaño de las etiquetas de la zona de impacto calculando el tamaño de las partes relevantes del texto. Este enfoque también tiene la ventaja de poder modificar el tamaño de las zonas de impacto para que sean más grandes y más fáciles de tocar con dedos gordos.

1

He implementado su pregunta, solo por diversión en my blog.

Simplemente he subclasificado UILabel sumando touchEnded, para reconocer la posición táctil y la posición de la letra.

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [[touches allObjects] objectAtIndex:0]; 
    CGPoint pos = [touch locationInView:self]; 

    int sizes[self.text.length]; 
    for (int i=0; i<self.text.length; i++) 
    { 
    char letter   = [self.text characterAtIndex:i]; 
    NSString *letterStr = [NSString stringWithFormat:@"%c", letter]; 

    CGSize letterSize = [letterStr sizeWithFont:self.font]; 
    sizes[i]   = letterSize.width; 
    } 

    int sum = 0; 
    for (int i=0; i<self.text.length; i++) 
    { 
    sum += sizes[i]; 
    if (sum >= pos.x) 
    { 
     [ _delegate didLetterFound:[ self.text characterAtIndex:i] ]; 
     return; 
    } 
    } 
} 

Esperanza esto ayuda
aplausos.

0

Tuve un problema similar al del original. Quería que el usuario pudiera presionar durante mucho tiempo en un UILabel que mostraba una lista de cadenas separadas por comas, y extraer una subcadena correspondiente a la ubicación táctil entre las comas más cercanas.

El problema es que UILabel no implementa el protocolo UITextInput; de lo contrario, la implementación sería sencilla.

No me gustaron ninguna de las soluciones alternativas que encontré, así que decidí buscar mi propia solución. Después de reflexionar e investigar, me di cuenta de que, si bien UILabel no es compatible con UITextInput, UITextView sí lo hace. No quería reemplazar todos los UILabels en la interfaz de usuario con UITextViews, así que pensé, "¿por qué no crear programáticamente un UITextView detrás de escena, con la misma configuración de representación de texto, y usar sus métodos UITextInput para mapear el punto de contacto a la subcadena deseada? ".

Esta resultó ser la solución ideal desde mi punto de vista.

Os adjunto un UILongPressGestureRecognizer a los UILabels y llame a la siguiente función en el controlador gesto:

-(NSString*)commaDelineatedTextAtTouchPosition:(UILongPressGestureRecognizer*)longPress 
{ 
    UILabel *gestureRecipient = (UILabel*)longPress.view; 
    UITextView *textRegionClone = [[UITextView alloc] initWithFrame:gestureRecipient.frame]; 

    // tweak the text view's content area to get the same rendering (placement and wrapping) 
    textRegionClone.textContainerInset = UIEdgeInsetsMake(0.0, -5.0, 0.0, -5.0); 
    // copy the label's text properties 
    textRegionClone.text = gestureRecipient.text; 
    textRegionClone.font = gestureRecipient.font; 
    [textRegionClone setNeedsDisplay]; 
    CGPoint loc = [longPress locationInView:gestureRecipient]; 
    UITextPosition *charR = [textRegionClone closestPositionToPoint:loc]; 

    id<UITextInputTokenizer> tokenizer = textRegionClone.tokenizer; 
    UITextRange *searchRange = [tokenizer rangeEnclosingPosition:charR withGranularity:UITextGranularityCharacter inDirection:UITextStorageDirectionBackward]; 
    NSString *commaEnclosedText = @""; 

    if (searchRange != nil) { 
     NSString *tapChar = [textRegionClone textInRange:searchRange]; 

     if ([tapChar isEqualToString:@","]) { // tapped right on a "," 
      // move the end of the range to immediately before the "," 
      searchRange = [textRegionClone textRangeFromPosition:searchRange.start toPosition:[textRegionClone positionFromPosition:searchRange.end offset:-1]]; 
     } 

     UITextPosition *docStart = textRegionClone.beginningOfDocument; 

     // search back to find the leading comma or the beginning of the text 
     do { 
      searchRange = [textRegionClone textRangeFromPosition:[textRegionClone positionFromPosition:searchRange.start offset:-1] toPosition:searchRange.end]; 
      commaEnclosedText = [textRegionClone textInRange:searchRange]; 
     } 
     while (([searchRange.start isEqual:docStart] == NO) && ([commaEnclosedText characterAtIndex:0] != ',')); 

     // now search forward to the trailing comma or the end of the text 
     UITextPosition *docEnd = textRegionClone.endOfDocument; 

     while (([searchRange.end isEqual:docEnd] == NO) && ([commaEnclosedText characterAtIndex:commaEnclosedText.length - 1] != ',')) { 
      searchRange = [textRegionClone textRangeFromPosition:searchRange.start toPosition:[textRegionClone positionFromPosition:searchRange.end offset:1]]; 
      commaEnclosedText = [textRegionClone textInRange:searchRange]; 
     } 

     commaEnclosedText = [[commaEnclosedText stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@","]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
    } 

    return commaEnclosedText; 
} 

La única cosa que es un poco hacky acerca de esta técnica es que usted tiene a mano modificar la forma en UITextView ajustando la región textContainerInset. De lo contrario, no obtendrá exactamente el mismo ajuste y colocación del texto en UITextView que en UILabel. De lo contrario, este es un código razonablemente genérico que debería funcionar para cualquier otra persona.

0

- (void)tapped:(UITapGestureRecognizer *)tap 
{ 
    CGPoint location = [tap locationInView:_label]; 

    NSDictionary *attribute = @{NSFontAttributeName: _label.font}; 
    CGFloat width = 0; 
    for (int i = 0; i substringWithRange:NSMakeRange(i, 1)]; 
     CGSize lettersize = [letterStr sizeWithAttributes:attribute]; 
     width += lettersize.width; 
     if (width >= location.x) { 
      NSLog(@"str: %@", letterStr); 
      break; 
     } 
    } 
}