2012-09-19 84 views
0

我正在使用核心文本進行文本選擇。選擇機制本身正在工作,除了一件非常奇怪的事情。我可以選擇文本視圖只有的最後一行罰款。之前的所有線都捕捉到全部選定的或未選中的全部。這裏是邏輯(取自Apple的示例代碼):CTFrameGetLineOrigin令人難以置信的奇怪錯誤

NSArray *lines = (NSArray *) CTFrameGetLines(_frame); 
for (int i = 0; i < [lines count]; i++) { 
    CTLineRef line = (CTLineRef) [lines objectAtIndex:i]; 
    CFRange lineRange = CTLineGetStringRange(line); 
    NSRange range = NSMakeRange(lineRange.location, lineRange.length); 
    NSRange intersection = [self RangeIntersection:range withSecond:selectionRange]; 
    if (intersection.location != NSNotFound && intersection.length > 0) { 
     // The text range for this line intersects our selection range 
     CGFloat xStart = CTLineGetOffsetForStringIndex(line, intersection.location, NULL); 
     CGFloat xEnd = CTLineGetOffsetForStringIndex(line, intersection.location + intersection.length, NULL); 
     CGPoint origin; 
     // Get coordinate and bounds information for the intersection text range 
     CTFrameGetLineOrigins(_frame, CFRangeMake(i, 0), &origin); 
     CGFloat ascent, descent; 
     CTLineGetTypographicBounds(line, &ascent, &descent, NULL); 
     // Create a rect for the intersection and draw it with selection color 
     CGRect selectionRect = CGRectMake(xStart, origin.y - descent, xEnd - xStart, ascent + descent); 
     UIRectFill(selectionRect); 
    } 
}  

我注意到一件很奇怪的事情。調用CTFrameGetLineOrigin似乎會破壞xStart和xEnd中的值。我插入日誌如下面的:

NSLog(@"BEFORE: xStart (%p) = %f, xEnd (%p) = %f, origin (%p) = %@", &xStart, xStart, &xEnd, xEnd, &origin, NSStringFromCGPoint(origin)); 
CTFrameGetLineOrigins(_frame, CFRangeMake(i, 0), &origin); 
NSLog(@"AFTER: xStart (%p) = %f, xEnd (%p) = %f, origin (%p) = %@", &xStart, xStart, &xEnd, xEnd, &origin, NSStringFromCGPoint(origin)); 

的輸出爲線不工作是如下

2012-09-19 12:08:39.831 SimpleTextInput [1172:11603]前:XSTART(0xbfffcefc)= 18.000000,XEND(0xbfffcef8)= 306.540009,原點(0xbfffcef0)= {0,-O}

2012-09-19 12:08:39.831 SimpleTextInput [1172:11603] AFTER:XSTART (0xbfffcefc)= 370.000000,xEnd(0xbfffcef8)= 0.000000,原點(0xbfffcef0)= {0,397}

如果我這樣做,它會自我修正......但我不知道爲什麼:

CGFloat xStart = CTLineGetOffsetForStringIndex(line, intersection.location, NULL); 
CGFloat xEnd = CTLineGetOffsetForStringIndex(line, intersection.location + intersection.length, NULL); 
CGFloat xStart2 = 0.f; //HACK, not used at all except to pad memory 
CGPoint origin; 

好像CTFrameGetLineOrigin不尊重的origin內存邊界(記錄xStart2顯示,其值以同樣的方式被破壞),但是如果是這種情況,那麼爲什麼最後一行文本按預期工作?誰可以給我解釋一下這個?

回答

3

CTFrameGetLineOrigins中沒有奇怪的錯誤。

在CTFrameGetLineOrigins第二個參數中:CFRange是您希望複製的行起點的範圍。 如果範圍的範圍長度爲0,則複製操作從範圍的開始索引繼續到最後一個原點。您要通過CFRangeMake(i, 0)。 這裏在第一次循環迭代中(i = 0),它會嘗試用所有行起點(0到結束行)填充&並覆蓋其他一些內存。

請嘗試下面的代碼,這將解決問題。

NSArray *lines = (NSArray *) CTFrameGetLines(_frame); 
CGPoint origins[lines.count]; //allocate enough space for buffer. 
// Get all line origins... 
CTFrameGetLineOrigins(_frame, CFRangeMake(0, 0), origins); 

for (int i = 0; i < [lines count]; i++) { 
    CTLineRef line = (CTLineRef) [lines objectAtIndex:i]; 
    CFRange lineRange = CTLineGetStringRange(line); 
    NSRange range = NSMakeRange(lineRange.location, lineRange.length); 
    NSRange intersection = [self RangeIntersection:range withSecond:selectionRange]; 
    if (intersection.location != NSNotFound && intersection.length > 0) { 
        // The text range for this line intersects our selection range 
        CGFloat xStart = CTLineGetOffsetForStringIndex(line, intersection.location, NULL); 
        CGFloat xEnd = CTLineGetOffsetForStringIndex(line, intersection.location + intersection.length, NULL); 
        
        CGFloat ascent, descent; 
        CTLineGetTypographicBounds(line, &ascent, &descent, NULL); 
        // Create a rect for the intersection and draw it with selection color 
        CGRect selectionRect = CGRectMake(xStart + origins[i].x, origins[i].y - descent, xEnd - xStart, ascent + descent); 
        UIRectFill(selectionRect); 
    } 
}     
+0

這實際上是我最終做的,但我不知道它爲什麼這樣工作。感謝您的解釋! – borrrden

0

這看起來就像是從SimpleTextInput例如drawRangeAsSelection。如果是這樣的話,你可以這樣做:

CTFrameGetLineOrigins(_frame, CFRangeMake(i, 1), &origin); 

這將簡單地檢索了你所需要(這是應該在這方法)的一條線的原點。我也注意到他們在以下方面犯了同樣的錯誤:cursorRectForIndexfirstRectForNSRange。感謝@RobNapier幫助我解決這個問題。

相關問題