我想在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);
}
}
答案 0 :(得分:1)
您可以使用点击手势获取点击位置,
你有CTFrame
,
然后就可以计算出需要的文本框了。
这是一个例子,如何计算点击位置的两个字符的框架。
传入CTFrame
和Tap 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为例