UILabel触摸并获取触摸的文本

时间:2010-12-07 03:11:46

标签: iphone uilabel

我的UILabel有一些文字和2个月的名字,如“在1月和7月,阳光将是最高峰” 我对UILabel进行了分类并添加了触摸事件。 现在我想在用户触摸的文本下面找到这个词,并找出用户是否触及1月/ 7月。有可能吗?

5 个答案:

答案 0 :(得分:3)

我想您会在UITextInputProtocol的文档中找到您要找的内容。

有关更高级别的信息,请查看Apple的Text, Web and Editing Guide,特别是在标题为“UITextInput实施的指导教程”的部分中。它讨论了如何在文本中创建索引位置,并询问他们最接近的文本位置。

Apple引用了一个名为SimpleTextInput的样本,但我似乎无法找到它。我会继续寻找。

答案 1 :(得分: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;
    }
  }
}

希望这会有所帮助 欢呼声。

答案 2 :(得分:0)

我通过在UILabel的顶部放置透明的UIViews来处理这个问题,这些UIFabel被连线以处理触摸事件。您可以通过计算文本相关部分的大小来调整命中区域标签的位置和大小。这种方法还具有以下优点:能够调整击中区域的大小,使其更大,更容易用肥胖的手指轻拍。

答案 3 :(得分:0)

我遇到了与原始海报类似的问题。我希望用户能够在显示逗号分隔的字符串列表的UILabel中长按,并提取与最接近的逗号之间的触摸位置对应的子字符串。

问题是UILabel没有实现UITextInput协议,否则实现会很简单。

我不喜欢我找到的任何建议的解决方法,所以我决定提出自己的解决方案。经过一番思考和研究,我意识到虽然UILabel不支持UITextInput,但UITextView却支持UIText。我不想用UITextViews替换UI中的所有UILabel,所以我想,“为什么不以编程方式在幕后创建UITextView,使用完全相同的文本渲染设置,并使用其UITextInput方法将触摸点映射到想要的子串?“

从我的角度来看,这被证明是理想的解决方案。

我将UILongPressGestureRecognizer附加到UILabels并在手势处理程序中调用以下函数:

-(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中的渲染。否则,您不会像在UILabel中那样在UITextView中获得完全相同的文本包装和放置。否则,这是适用于其他任何人的通用代码。

答案 4 :(得分: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;
        }
    }
}