2010-12-07 2 views
6

"1 월과 7 월의 달에 일조량이 최고 일 것"이라는 UILabel을 사용했습니다. 하위 분류 된 UILabel을 터치 이벤트에 추가했습니다. . 이제 사용자가 터치 한 텍스트 아래에 단어를 가져 와서 사용자가 1 월/7 월을 터치했는지 여부를 확인하고자합니다. 가능한가?UILabel 터치하고 만진 곳에서 텍스트를 가져옵니다.

답변

3

UITextInputProtocol에 대한 설명서에서 원하는 내용을 찾을 수있을 것입니다.

더 높은 수준의 정보는 Apple Text, Web and Editing Guide의 "UITextInput 구현 가이드 투어"섹션을 참조하십시오. 텍스트에서 인덱싱 된 위치를 만드는 방법과 가장 가까운 텍스트 위치를 묻는 방법에 대해 설명합니다.

Apple의 참조 프로젝션은 SimpleTextInput이지만 예상대로 찾을 수 없습니다. 나는 계속 볼거야.

+0

사용 방법에 대한 샘플이나 가이드가 있습니까? – Satyam

+0

안녕하세요, 애플이 샘플 코드를 언급했습니다 - 지금 찾을 수 있는지 알아보기 위해 노력하고 있습니다. –

+0

Now (2011-01-19) 사용 가능 : http://developer.apple.com/library/ios/#samplecode/SimpleTextInput/Introduction/Intro.html – Stephan

0

나는 터치 이벤트를 처리하도록 유선 UILabel 위에 transaparent UIViews를 두어이 문제를 처리했습니다. 텍스트의 관련 부분의 크기를 계산하여 적중 영역 레이블의 위치와 크기를 조정할 수 있습니다. 이 방법은 또한 히트 영역의 크기를 조정하여 뚱뚱한 손가락으로 더 크고 더 쉽게 탭할 수 있다는 이점이 있습니다.

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로 바꾸고 싶지 않았기 때문에 "정확한 UITextInput 메서드를 사용하여 프로그래밍 방식으로 UITextView를 장면과 동일한 텍스트 렌더링 설정으로 만들어야하는 이유는 무엇입니까? 원하는 하위 문자열? ".

이것은 내 관점에서 볼 때 이상적인 해결책입니다.

은 내가 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; 
     } 
    } 
}