2010-12-07 23 views
6

私はUILabelに「1月と7月の月に太陽が輝きます」というようなテキストと2か月の名前を付けました サブクラスのUILabelをサブクラス化し、タッチイベントを追加しました。 ここでは、ユーザーが触れたテキストの下に単語を入れて、ユーザーが1月/ 7月に触れたかどうかを調べたいと思います。出来ますか?UILabelタッチしてタッチした場所にテキストを取得

答えて

3

あなたが探しているものはUITextInputProtocolのドキュメントにあります。

さらに詳しい情報については、アップルのText, Web and Editing Guide、特に「UITextInput実装ガイドツアー」のセクションを参照してください。テキスト内のインデックス付きの位置を作成して、どのテキストの位置が最も近いかを調べる方法について説明します。

アップルの参考資料は、SimpleTextInputという名前の投影されたサンプルですが、見つからないようです。私は見続けるだろう。

+0

使用方法に関するサンプルやチュートリアルはありますか? – Satyam

+0

ちょっと、アップルはサンプルコードを引用しました - 私は今それを見つけることができるかどうかを試してみてください。 –

+0

Now(2011-01-19)はこちらから入手できます:http://developer.apple.com/library/ios/#samplecode/SimpleTextInput/Introduction/Intro.html – Stephan

0

タッチイベントを処理するために配線されたUILabelの上にトランスペアレントなUIViewを配置することでこの問題を処理しました。テキストの関連部分のサイズを計算することによって、ヒットゾーンラベルの位置とサイズを調整できます。このアプローチにはヒットゾーンのサイズを微調整して、太い指で大きくて簡単にタップすることができるという利点もあります。

1

あなたの質問は、my blogで楽しみにして実装しました。

私は単にUILabelをサブクラス化して、タッチ位置と文字位置を認識するためにtouchEndedを追加しました。

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

が、これは
歓声がお役に立てば幸いです。

0

私は元のポスターと同様の問題がありました。カンマで区切られた文字列のリストを表示していたUILabelを長押しして、最も近い囲みカンマの間のタッチ位置に対応するサブストリングを抽出できるようにしたいと思っていました。

問題は、UILabelがUITextInputプロトコルを実装していないことです。そうでないと、実装は簡単になります。

私が見つけた推奨回避策が嫌いでしたので、私自身の解決策を考え出しました。いくつかの考えと研究の後、UILabelはUITextInputをサポートしていませんが、UITextViewはサポートしています。 UIのすべてのUILabelsをUITextViewsに置き換えたいとは思わなかったので、私は「プログラムでUITextViewをバックグラウンドで作成し、全く同じテキストレンダリング設定で作成し、そのUITextInputメソッドを使用してタッチポイントを所望の部分文字列「?

これは私の視点から理想的な解決策であることが分かりました。

私はUILabelsにUILongPressGestureRecognizerを取り付け、ジェスチャーハンドラに次の関数を呼び出します。

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

この技術について少しハックだ唯一のことは、あなたが手で微調整レンダリング中に持っているということですtextContainerInset領域を調整してUITextViewを作成します。それ以外の場合は、UITextViewでのテキストの折り返しと配置を、UILabelでの場合とまったく同じにすることはできません。それ以外の場合は、これは誰にとってもうまくいく、合理的に一般的なコードです。

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; 
     } 
    } 
} 
関連する問題