CoreText库中使用CTFramesetter,根据文本内容实现丰富的Frame

//textContent:要在Frame中填充的文本内容

CFMutableAttributedStringRef attributeRef = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);

CFAttributedStringReplaceString(attributeRef, CFRangeMake(0, 0), (CFStringRef)textContent);

//设定文本格式

CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

CGFloat components[] = { 60/255.0, 60/255.0, 60/255.0, 1.0 };

CGColorRef color = CGColorCreate(colorspace, components);

CGColorSpaceRelease(colorspace);



int count = [textContent length];

CFAttributedStringSetAttribute(attributeRef, CFRangeMake(0, count), kCTForegroundColorAttributeName,color);

CGColorRelease(color);



CTFontRef font = CTFontCreateWithName((CFStringRef)@"Arial", fontSize, nil);

//CTFontRef font = CTFontCreateWithName(CFSTR("Times New Roman"), fontSize, nil);

CFAttributedStringSetAttribute(attributeRef, CFRangeMake(0, count), kCTFontAttributeName,font);

CFRelease(font);

{

//行距

CFIndex theNumberOfSettings = 4;

CTTextAlignment theAlignment = kCTJustifiedTextAlignment;

CTLineBreakMode theBreakMode = kCTLineBreakByCharWrapping;

CGFloat theFirstLineHeadIndent = fontSize*2;

CTParagraphStyleSetting theSettings[4] =

{

{ kCTParagraphStyleSpecifierLineSpacing, sizeof(CGFloat), &lineSpacing},

{ kCTParagraphStyleSpecifierAlignment, sizeof(CTTextAlignment),&theAlignment },

{ kCTParagraphStyleSpecifierLineBreakMode, sizeof(CTLineBreakMode), &theBreakMode },

{ kCTParagraphStyleSpecifierFirstLineHeadIndent, sizeof(CGFloat), &theFirstLineHeadIndent}

};

CTParagraphStyleRef theParagraphRef = CTParagraphStyleCreate(theSettings, theNumberOfSettings);

CFAttributedStringSetAttribute((CFMutableAttributedStringRef)attributeRef, CFRangeMake(0, [textContent length]), kCTParagraphStyleAttributeName, theParagraphRef);

CFRelease(theParagraphRef);

}

//开始绘制

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attributeRef);

{

CFRange range = CFRangeMake(0, 0);

CFRange curRange = CFRangeMake(0, 0);

CFIndex lastPageLines = 0;

CGPoint preTextPoint = textPoint;

CGRect otherRect;



//获取size的大小以计算最终坐标

{

CGRect textFrame;

textFrame = CGRectMake(preTextPoint.x, preTextPoint.y, ArticleBodyWidth, CGFLOAT_MAX);

[self writeLogFrame:textFrame];

CGMutablePathRef pathRef = CGPathCreateMutable();

CGPathAddRect(pathRef,NULL,textFrame);

CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, range, pathRef, NULL);


curRange = CTFrameGetVisibleStringRange(frameRef);//读取当前Range,以判断是否完成,to do

lastPageLines += CFArrayGetCount(CTFrameGetLines(frameRef));//获取行数

CFRelease(frameRef);

CGPathRelease(pathRef);



textPoint = CGPointMake(textPoint.x, textPoint.y+ lastPageLines*(fontSize+lineSpacing)+5);

otherRect = CGRectMake(textPoint.x, textPoint.y, ArticleBodyWidth, textPoint.y);

}

//开始执行绘制,组合

{

CFRange range = CFRangeMake(0, 0);

CFRange curRange = CFRangeMake(0, 0);

CFIndex lastPageLines = 0;

CGRect textFrame;



textFrame = CGRectMake(preTextPoint.x, preTextPoint.y, otherRect.size.width, otherRect.size.height);



[self writeLogFrame:textFrame];

CGMutablePathRef pathRef = CGPathCreateMutable();

CGPathAddRect(pathRef,NULL,textFrame);

CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, range, pathRef, NULL);

//frameArray中存储所有完成的frame
CFArrayAppendValue(frameArray, frameRef);
curRange = CTFrameGetVisibleStringRange(frameRef);

lastPageLines += CFArrayGetCount(CTFrameGetLines(frameRef));

textPoint = CGPointMake(textPoint.x, preTextPoint.y + lastPageLines*(fontSize+lineSpacing)+5);



CFRelease(frameRef);

CGPathRelease(pathRef);

}

}

CFRelease(framesetter);

CFRelease(attributeRef);

完成frame在内存中的设置后,开始进行绘制。

注意:

CTFramesetterRef中的坐标和objc的UI坐标相反,需要在执行绘制事调整坐标「y轴相反,文本相反」顺序填充,所以在对frame进行设置时要预考虑各frame调整后的坐标是否正确。

-(void)drawRect:(CGRect)rect
{
if (0 == CFArrayGetCount(frameArray)) {
return;
}
NSLog(@"-->self frame height = %f",self.frame.size.height);
// 调整坐标
CGContextRef context = UIGraphicsGetCurrentContext();
{
CGAffineTransform textTran = CGAffineTransformIdentity;
textTran = CGAffineTransformMakeTranslation(0.0, self.frame.size.height);
textTran = CGAffineTransformScale(textTran, 1.0, -1.0);
CGContextConcatCTM(context, textTran);
}
//向矩形框中填充内容
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
for (int i=0; i<CFArrayGetCount(frameArray); i++) {
CTFrameRef frameRef = CFArrayGetValueAtIndex(frameArray, i);

CTFrameDraw(frameRef,context);
}

}

官方解释

CGAffineTransformMakeTranslation

Returns an affine transformation matrix constructed from translation values you provide.

CGAffineTransform CGAffineTransformMakeTranslation (
CGFloat tx,
CGFloat ty
);
Parameters
tx

The value by which to move the x-axis of the coordinate system.

ty

The value by which to move the y-axis of the coordinate system.

Return Value

A new affine transform matrix.

CGAffineTransformScale

Returns an affine transformation matrix constructed by scaling an existing affine transform.

CGAffineTransform CGAffineTransformScale (
CGAffineTransform t,
CGFloat sx,
CGFloat sy
);
Parameters
t

An existing affine transform.

sx

The value by which to scale x values of the affine transform.

sy

The value by which to scale y values of the affine transform.

Return Value

A new affine transformation matrix.



转载于:https://www.cnblogs.com/dotapp/archive/2012/03/05/2380438.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值