2013-02-06 25 views
5

Tôi có một số UITextView hiển thị đoạn văn. Ví dụ:Xử lý sự kiện cảm ứng UITextView khi chạm vào một từ trong đó

self.myTextView.text = @"This is a sample paragraph" 

Những gì tôi muốn làm bây giờ là khi tôi chạm lên một từ trong văn bản này, chẳng hạn như "Đây", một chức năng sẽ được gọi: [self aFunction:@"This"]

Có bất kỳ ý tưởng để xử lý sự kiện này và cách để có được tham số, đó là từ người dùng chạm vào. Có lẽ, tôi cần cách khác để hiển thị đoạn văn, chứ không phải bởi UITextView.

+0

U sẽ phải làm cho điều đó từ một siêu liên kết .... – IronManGill

+0

@ Gill-TheIronMan: sau đó ông cần phải làm cho toàn bộ văn bản như các siêu liên kết cũng không thể trong tình huống này. –

+0

Câu hỏi hay, tôi cũng đang đợi xem giải pháp :) –

Trả lời

1

Trong theo gương sử dụng (UITextView)

Tôi tạo ra một lớp con UILabel đơn giản cho phép tôi để thiết lập giá trị inset:

#import "WWLabel.h" 

#define WWLabelDefaultInset 5 

@implementation WWLabel 

@synthesize topInset, leftInset, bottomInset, rightInset; 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.topInset = WWLabelDefaultInset; 
     self.bottomInset = WWLabelDefaultInset; 
     self.rightInset = WWLabelDefaultInset; 
     self.leftInset = WWLabelDefaultInset; 
    } 
    return self; 
} 

- (void)drawTextInRect:(CGRect)rect 
{ 
    UIEdgeInsets insets = {self.topInset, self.leftInset, 
     self.bottomInset, self.rightInset}; 

    return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)]; 
} 

Sau đó, tôi đã tạo ra một phân lớp UIView có chứa nhãn tùy chỉnh của tôi , và khi nhấn xây dựng kích thước của văn bản cho mỗi từ trong nhãn, cho đến khi kích thước vượt quá kích thước của vị trí nhấn - đây là từ đã được nhấn. Nó không phải là hoàn hảo, nhưng bây giờ vẫn hoạt động tốt.

sau đó tôi đã sử dụng một NSAttributedString đơn giản để đánh dấu văn bản:

#import "WWPhoneticTextView.h" 
#import "WWLabel.h" 

#define WWPhoneticTextViewInset 5 
#define WWPhoneticTextViewDefaultColor [UIColor blackColor] 
#define WWPhoneticTextViewHighlightColor [UIColor yellowColor] 

#define UILabelMagicTopMargin 5 
#define UILabelMagicLeftMargin -5 

@implementation WWPhoneticTextView { 
    WWLabel *label; 
    NSMutableAttributedString *labelText; 
    NSRange tappedRange; 
} 

// ... skipped init methods, very simple, just call through to configureView 

- (void)configureView 
{ 
    if(!label) { 
     tappedRange.location = NSNotFound; 
     tappedRange.length = 0; 

     label = [[WWLabel alloc] initWithFrame:[self bounds]]; 
     [label setLineBreakMode:NSLineBreakByWordWrapping]; 
     [label setNumberOfLines:0]; 
     [label setBackgroundColor:[UIColor clearColor]]; 
     [label setTopInset:WWPhoneticTextViewInset]; 
     [label setLeftInset:WWPhoneticTextViewInset]; 
     [label setBottomInset:WWPhoneticTextViewInset]; 
     [label setRightInset:WWPhoneticTextViewInset]; 

     [self addSubview:label]; 
    } 


    // Setup tap handling 
    UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] 
               initWithTarget:self action:@selector(handleSingleTap:)]; 
    singleFingerTap.numberOfTapsRequired = 1; 
    [self addGestureRecognizer:singleFingerTap]; 
} 

- (void)setText:(NSString *)text 
{ 
    labelText = [[NSMutableAttributedString alloc] initWithString:text]; 
    [label setAttributedText:labelText]; 
} 

- (void)handleSingleTap:(UITapGestureRecognizer *)sender 
{ 
    if (sender.state == UIGestureRecognizerStateEnded) 
    { 
     // Get the location of the tap, and normalise for the text view (no margins) 
     CGPoint tapPoint = [sender locationInView:sender.view]; 
     tapPoint.x = tapPoint.x - WWPhoneticTextViewInset - UILabelMagicLeftMargin; 
     tapPoint.y = tapPoint.y - WWPhoneticTextViewInset - UILabelMagicTopMargin; 

     // Iterate over each word, and check if the word contains the tap point in the correct line 
     __block NSString *partialString = @""; 
     __block NSString *lineString = @""; 
     __block int currentLineHeight = label.font.pointSize; 
     [label.text enumerateSubstringsInRange:NSMakeRange(0, [label.text length]) options:NSStringEnumerationByWords usingBlock:^(NSString* word, NSRange wordRange, NSRange enclosingRange, BOOL* stop){ 

      CGSize sizeForText = CGSizeMake(label.frame.size.width-2*WWPhoneticTextViewInset, label.frame.size.height-2*WWPhoneticTextViewInset); 
      partialString = [NSString stringWithFormat:@"%@ %@", partialString, word]; 

      // Find the size of the partial string, and stop if we've hit the word 
      CGSize partialStringSize = [partialString sizeWithFont:label.font constrainedToSize:sizeForText lineBreakMode:label.lineBreakMode]; 

      if (partialStringSize.height > currentLineHeight) { 
       // Text wrapped to new line 
       currentLineHeight = partialStringSize.height; 
       lineString = @""; 
      } 
      lineString = [NSString stringWithFormat:@"%@ %@", lineString, word]; 

      CGSize lineStringSize = [lineString sizeWithFont:label.font constrainedToSize:label.frame.size lineBreakMode:label.lineBreakMode]; 
      lineStringSize.width = lineStringSize.width + WWPhoneticTextViewInset; 

      if (tapPoint.x < lineStringSize.width && tapPoint.y > (partialStringSize.height-label.font.pointSize) && tapPoint.y < partialStringSize.height) { 
       NSLog(@"Tapped word %@", word); 
       if (tappedRange.location != NSNotFound) { 
        [labelText addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:tappedRange]; 
       } 

       tappedRange = wordRange; 
       [labelText addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:tappedRange]; 
       [label setAttributedText:labelText]; 
       *stop = YES; 
      } 
     }];   
    } 
} 
+0

Cảm ơn bạn rất nhiều! Tôi sẽ thử nó. – hnimnart

+0

Tôi đã thấy theo cách của bạn, nhưng tôi đã không thực hiện được nó và bây giờ đang tìm lỗi. – hnimnart

Các vấn đề liên quan