您的位置:首页 > 移动开发 > IOS开发

iOS 获取label上点击位置的字符位置

2017-03-15 14:04 405 查看
手势点击事件

-(void)dotap:(UITapGestureRecognizer *)tap

{

    

    CGPoint point=[tap
locationInView:self.tableView];

    NSIndexPath *indexpath=[self.tableView
indexPathForRowAtPoint:point];

    if (indexpath) {

        ChatTableViewCell *cell=[self.tableView
cellForRowAtIndexPath:indexpath];

        

        UILabel *lable=nil;

        for (UIView *view
in cell.contentView.subviews) {

            

            if ([view
isKindOfClass:[UILabel
class]]) {

                lable=(UILabel*)view;

                break;

            }

        }

        CGPoint p = [tap
locationInView:cell];

        if (CGRectContainsPoint(lable.frame, p)) {

            NSError *error =
NULL;

            

            NSDataDetector *detector = [NSDataDetector
dataDetectorWithTypes:NSTextCheckingTypeLink
error:&error];

            

            self.matches = [detector
matchesInString:lable.text
options:0 range:NSMakeRange(0, lable.text.length)];

            

            //CFIndex index = [self characterIndexAtPoint:[tap locationInView:lable]];

            CFIndex index=[self
getindexArrayOfStringInLabel:lable
Point:[tap locationInView:lable]];

            

            NSLog(@"index=%ld",index);

            

            

            

            for (NSTextCheckingResult *match
in self.matches) {

                

                if ([match
resultType] == NSTextCheckingTypeLink) {

                    

                    NSRange matchRange = [match
range];

                    

                    if ([self
isIndex:index inRange:matchRange]) {

                       // NSLog(@"点击跳转页面");

                        NSLog(@"matchRange=%@",[lable.text
substringWithRange:matchRange]);

                        

                        

                       // [[UIApplication sharedApplication] openURL:match.URL];

                        break;

                    }

                }

            }

        }

    }

    

}

- (BOOL)isIndex:(CFIndex)index inRange:(NSRange)range {

    return index >= range.location && index <= range.location+range.length;

}

#pragma mark -****获取lable中的点击位置的字符的index

-(CFIndex)getindexArrayOfStringInLabel:(UILabel *)label Point:(CGPoint)point

{

    NSString *text = [label
text];

    UIFont   *font = [label
font];

    CGRect    rect = [label
bounds];

    

   // point = CGPointMake(point.x - rect.origin.x, point.y - rect.origin.y);

    // Convert tap coordinates (start at top left) to CT coordinates (start at bottom left)
坐标系反转

    point = CGPointMake(point.x, rect.size.height
- point.y);

    

    NSUInteger idx =
NSNotFound;

    CTFontRef myFont =
CTFontCreateWithName((CFStringRef)font.fontName,

                                            font.pointSize,

                                            NULL);

    

    NSMutableAttributedString *attStr = [[NSMutableAttributedString
alloc] initWithString:text];

    [attStr addAttribute:(NSString *)kCTFontAttributeName
value:(__bridge
id)myFont
range:NSMakeRange(0, attStr.length)];

    

    CTFramesetterRef frameSetter =
CTFramesetterCreateWithAttributedString((__bridge
CFAttributedStringRef)attStr);

    

    CGMutablePathRef path =
CGPathCreateMutable();

    CGPathAddRect(path,
NULL,
CGRectMake(0,0,rect.size.width,rect.size.height+20));

    

    CTFrameRef frame =
CTFramesetterCreateFrame(frameSetter,
CFRangeMake(0, 0), path,
NULL);

    

   // NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);

    CFArrayRef lines =
CTFrameGetLines(frame);

    NSInteger numberOfLines =CFArrayGetCount(lines);

    NSLog(@"numberOfLines=%ld",(long)numberOfLines);

    

    CGPoint lineOrigins[numberOfLines];

    

    CTFrameGetLineOrigins(frame,
CFRangeMake(0, numberOfLines), lineOrigins);

    for (CFIndex lineIndex = 0; lineIndex < numberOfLines; lineIndex++) {

        CGPoint lineOrigin = lineOrigins[lineIndex];

        CTLineRef line =
CFArrayGetValueAtIndex(lines, lineIndex);

        CGFloat ascent, descent, leading, width;

        width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

        CGFloat yMin =
floor(lineOrigin.y - descent);

        CGFloat yMax =
ceil(lineOrigin.y + ascent);

        if (point.y > yMax) {

            break;

        }

        if (point.y >= yMin) {

            

            // Check if the point is within this line horizontally

            if (point.x >= lineOrigin.x && point.x
<= lineOrigin.x + width) {

                

                // Convert CT coordinates to line-relative coordinates

                CGPoint relativePoint =
CGPointMake(point.x - lineOrigin.x, point.y
- lineOrigin.y);

                idx = CTLineGetStringIndexForPosition(line, relativePoint);

                

                break;

            }

        }

        

    }

   

    return idx;

    

    

    

  

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: