コアテキストを使用したテキスト選択に取り組んでいます。非常に奇妙なことを除いて、選択メカニズム自体は機能しています。テキストビューの最終行でのみファインを選択できます。以前のすべての行は、すべて選択されているか、まったく選択されていないかのいずれかにスナップします。ロジックは次のとおりです(Appleのサンプルコードから取得)。
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、origin(0xbfffcef0)= {0、-0}
2012-09-19 12:08:39.831 SimpleTextInput [1172:11603] AFTER:xStart(0xbfffcefc)= 370.000000、xEnd(0xbfffcef8)= 0.000000、origin(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
は、その値が同じように破損していることを示しています)が、その場合、テキストの最後の行が期待どおりに機能するのはなぜですか?誰かが私にこれを説明できますか?