CoreText,复制和粘贴

时间:2012-01-04 06:52:11

标签: iphone ios copy paste core-text

我想在CoreText中使用UIMenuController,但是我不能选择单词,我想我必须计算单词的坐标,但坐标不能与NSRange对应。是否有任何函数可以解决它?< / p> 抱歉,我的英语不好〜 这是我的代码

CFArrayRef lines = CTFrameGetLines(leftFrame);
CFIndex i, total = CFArrayGetCount(lines);


CGFloat y;
for (i = 0; i < total; i++) {
    CGPoint origins;
    CTFrameGetLineOrigins( leftFrame, CFRangeMake(i, 1), &origins);


    CTLineRef line = (CTLineRef)CFArrayGetValueAtIndex(lines, i);

    y = self.bounds.origin.y + self.bounds.size.height - origins.y;

    //CTLineDraw(line, UIGraphicsGetCurrentContext());
    CFArrayRef runs = CTLineGetGlyphRuns(line);
    CFIndex r, runsTotal = CFArrayGetCount(runs);
    //NSLog(@"runsTotal = %d",runsTotal);
    for (r = 0; r < runsTotal; r++) {

        CGRect runBounds = CTRunGetImageBounds(CFArrayGetValueAtIndex(runs, r), context, CFRangeMake(0, 0));

        NSLog(@"runBounds.x = %f,runBounds.y = %f",runBounds.origin.x,runBounds.origin.y);
        CFIndex index =  CTRunGetStringRange(CFArrayGetValueAtIndex(runs, r)).location;

        //NSLog(@"%d",index);

    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用点击手势获取点击位置,

你有CTFrame

然后就可以计算出需要的文本框了。


这是一个例子,如何计算点击位置的两个字符的框架。

传入CTFrameTap Point,得到两个字符的frame及其在CTFrame中的范围

+(CGRect)parserRectWithPoint:(CGPoint)point range:(NSRange *)selectRange frameRef:(CTFrameRef)frameRef
{
    CFIndex index = -1;
    CGPathRef pathRef = CTFrameGetPath(frameRef);
    CGRect bounds = CGPathGetBoundingBox(pathRef);
    CGRect rect = CGRectZero;
    
    // get lines
    NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frameRef);
    if (!lines) {
        return rect;
    }
    NSInteger lineCount = [lines count];
    // prepare for origins of each line
    CGPoint *origins = malloc(lineCount * sizeof(CGPoint)); 
    if (lineCount) {
        CTFrameGetLineOrigins(frameRef, CFRangeMake(0, 0), origins);
        
        // check tap point in every line
        // found, then break
        for (int i = 0; i<lineCount; i++) {
            CGPoint baselineOrigin = origins[i];
            CTLineRef line = (__bridge CTLineRef)[lines objectAtIndex:i];
            CGFloat ascent,descent,linegap; //声明字体的上行高度和下行高度和行距
            CGFloat lineWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &linegap);
            CGRect lineFrame = CGRectMake(baselineOrigin.x, CGRectGetHeight(bounds)-baselineOrigin.y-ascent, lineWidth, ascent+descent+linegap+[LSYReadConfig shareInstance].lineSpace);   
            if (CGRectContainsPoint(lineFrame,point)){
                // line found 
                CFRange stringRange = CTLineGetStringRange(line);
                // glyph found
                index = CTLineGetStringIndexForPosition(line, point);
                CGFloat xStart = CTLineGetOffsetForStringIndex(line, index, NULL);
                CGFloat xEnd;
                // choose two words by default
                if (index > stringRange.location+stringRange.length-2) {
                    xEnd = xStart;
                    xStart = CTLineGetOffsetForStringIndex(line,index-2,NULL);
                    (*selectRange).location = index-2;
                }
                else{
                    xEnd = CTLineGetOffsetForStringIndex(line,index+2,NULL);
                    (*selectRange).location = index;
                }
                // choose two character
                (*selectRange).length = 2;
                rect = CGRectMake(origins[i].x+xStart,baselineOrigin.y-descent,fabs(xStart-xEnd), ascent+descent);
                
                break;
            }
        }
    }
    free(origins);
    return rect;
}

答案 1 :(得分:0)

核心文字不支持文字选择,您需要自己动手,请按照EGOTextView为例