2010-12-07 8 views
6

Ich habe UILabel, die einige Text und 2 Monate Namen wie "Im Monat Januar und Juli hat, wird die Sonne Höhepunkt sein" Ich unterklassifizierte UILabel und Touch-Event hinzugefügt . Jetzt möchte ich das Wort unter dem Text, wo Benutzer berührt und herausfinden, ob der Benutzer Januar/Juli berührt oder nicht. Ist es möglich?UILabel berühren und den Text, wo berührt zu bekommen

Antwort

3

Ich denke, dass Sie finden, was Sie in der Dokumentation für UITextInputProtocol finden.

Weitere Informationen auf hoher Ebene finden Sie unter Apples Text, Web and Editing Guide, insbesondere im Abschnitt "Eine geführte Tour einer UITextInput-Implementierung". Es wird erläutert, wie Sie indizierte Positionen im Text erstellen können, und fragt, welche Textposition am nächsten gelandet ist.

Apples Referenzen projiziert ein Beispiel SimpleTextInput, aber ich kann nicht scheinen, es zu finden. Ich werde weiter suchen.

+0

Haben Sie ein Beispiel oder ein Tutorial zur Verwendung? – Satyam

+0

hey, Apple erwähnt Beispielcode - versuchen zu sehen, ob ich es jetzt finden kann. –

+0

Jetzt (2011-01-19) ist es hier verfügbar: http://developer.apple.com/library/ios/#samplecode/SimpleTextInput/Introduction/Intro.html – Stephan

0

Ich behandelte dieses Problem, indem ich transaktionsreiche UIViews auf die UILabel legte, die mit Berührungsereignissen verbunden waren. Sie können die Position und Größe der Trefferzonenbeschriftungen anpassen, indem Sie die Größe der relevanten Textabschnitte berechnen. Dieser Ansatz hat auch den Vorteil, dass Sie die Größe Ihrer Trefferzonen optimieren können, um sie größer zu machen und so leichter mit fetten Fingern zu klopfen.

1

Ich habe Ihre Frage nur zum Spaß auf my blog umgesetzt.

Einfach habe ich UILabeltouchEnded subclassed, um Berührungsposition und Briefposition zu erkennen.

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

hoffe, das hilft
prost.

0

Ich hatte ein ähnliches Problem wie das Original-Poster. Ich wollte, dass der Benutzer ein UILabel lang drücken konnte, das eine durch Kommas getrennte Liste von Strings enthielt, und eine Sub-Zeichenkette entsprechend der Berührungsposition zwischen den nächsten einschließenden Kommas extrahieren.

Das Problem ist, dass UILabel das UITextInput-Protokoll nicht implementiert, andernfalls wäre die Implementierung einfach.

Ich mochte keine der vorgeschlagenen Problemumgehungen, die ich fand, also entschied ich mich, meine eigene Lösung zu finden. Nach einigem Nachdenken und Nachforschen stellte ich fest, dass UILabel UITextInput nicht unterstützt, UITextView jedoch. Ich wollte nicht alle UILabels in der Benutzeroberfläche durch UITextViews ersetzen, also dachte ich mir: "Warum nicht programmatisch ein UITextView hinter den Kulissen mit den exakt gleichen Einstellungen für die Textwiedergabe erstellen und seine UITextInput-Methoden verwenden, um den Berührungspunkt zuzuordnen die gewünschte Sub-String? ".

Dies erwies sich aus meiner Sicht als die ideale Lösung.

angebracht ich einen UILongPressGestureRecognizer den UILabels und die folgende Funktion in der Geste Handler aufrufen:

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

Das einzige, was ein wenig hacky über diese Technik ist, dass Sie die Rendering-Hand-zwicken in die UITextView durch Anpassen der textContainerInset-Region. Ansonsten erhalten Sie nicht genau das gleiche Umbrechen und Platzieren des Textes in der UITextView wie in UILabel. Ansonsten handelt es sich um einen generischen Code, der für alle anderen funktionieren sollte.

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; 
     } 
    } 
}