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

手势点击事件

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

    

    

    

  

}




你可能感兴趣的:(iOS 获取label上点击位置的字符位置)