IOS 圖文混排(CoreText.framework)詳解及實(shí)例
IOS 圖文混排(CoreText.framework)
本文主要介紹了IOS圖文混排的資料,這里整理了在網(wǎng)上查找的內(nèi)容,幫助理解,掌握這部分知識(shí),以下就是整理的內(nèi)容:
利用CORETEXT進(jìn)行圖文混排。
實(shí)現(xiàn)代碼:
void RunDelegateDeallocCallback( void* refCon ){
}
CGFloat RunDelegateGetAscentCallback( void *refCon ){
NSString *imageName = (NSString *)refCon;
return 80;//[UIImage imageNamed:imageName].size.height;
}
CGFloat RunDelegateGetDescentCallback(void *refCon){
return 0;
}
CGFloat RunDelegateGetWidthCallback(void *refCon){
NSString *imageName = (NSString *)refCon;
return 100;//[UIImage imageNamed:imageName].size.width;
}
先設(shè)置一個(gè)CTRun的委托,主要是用于指定對(duì)象的上行高,寬,或上下文釋放時(shí)使用。
-(void)drawCharAndPicture
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextMatrix(context, CGAffineTransformIdentity);//設(shè)置字形變換矩陣為CGAffineTransformIdentity,也就是說(shuō)每一個(gè)字形都不做圖形變換
CGAffineTransform flipVertical = CGAffineTransformMake(1,0,0,-1,0,self.bounds.size.height);
CGContextConcatCTM(context, flipVertical);//將當(dāng)前context的坐標(biāo)系進(jìn)行flip
NSLog(@"bh=%f",self.bounds.size.height);
NSMutableAttributedString *attributedString = [[[NSMutableAttributedString alloc] initWithString:@"請(qǐng)?jiān)谶@里插入一張圖片位置"] autorelease];
//為圖片設(shè)置CTRunDelegate,delegate決定留給圖片的空間大小
NSString *imgName = @"img.png";
CTRunDelegateCallbacks imageCallbacks;
imageCallbacks.version = kCTRunDelegateVersion1;
imageCallbacks.dealloc = RunDelegateDeallocCallback;
imageCallbacks.getAscent = RunDelegateGetAscentCallback;
imageCallbacks.getDescent = RunDelegateGetDescentCallback;
imageCallbacks.getWidth = RunDelegateGetWidthCallback;
CTRunDelegateRef runDelegate = CTRunDelegateCreate(&imageCallbacks, imgName);
NSMutableAttributedString *imageAttributedString = [[NSMutableAttributedString alloc] initWithString:@" "];//空格用于給圖片留位置
[imageAttributedString addAttribute:(NSString *)kCTRunDelegateAttributeName value:(id)runDelegate range:NSMakeRange(0, 1)];
CFRelease(runDelegate);
[imageAttributedString addAttribute:@"imageName" value:imgName range:NSMakeRange(0, 1)];
[attributedString insertAttributedString:imageAttributedString atIndex:4];
//換行模式
CTParagraphStyleSetting lineBreakMode;
CTLineBreakMode lineBreak = kCTLineBreakByCharWrapping;
lineBreakMode.spec = kCTParagraphStyleSpecifierLineBreakMode;
lineBreakMode.value = &lineBreak;
lineBreakMode.valueSize = sizeof(CTLineBreakMode);
CTParagraphStyleSetting settings[] = {
lineBreakMode
};
CTParagraphStyleRef style = CTParagraphStyleCreate(settings, 1);
// build attributes
NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObject:(id)style forKey:(id)kCTParagraphStyleAttributeName ];
// set attributes to attributed string
[attributedString addAttributes:attributes range:NSMakeRange(0, [attributedString length])];
CTFramesetterRef ctFramesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attributedString);
CGMutablePathRef path = CGPathCreateMutable();
CGRect bounds = CGRectMake(0.0, 0.0, self.bounds.size.width, self.bounds.size.height);
CGPathAddRect(path, NULL, bounds);
CTFrameRef ctFrame = CTFramesetterCreateFrame(ctFramesetter,CFRangeMake(0, 0), path, NULL);
CTFrameDraw(ctFrame, context);
CFArrayRef lines = CTFrameGetLines(ctFrame);
CGPoint lineOrigins[CFArrayGetCount(lines)];
CTFrameGetLineOrigins(ctFrame, CFRangeMake(0, 0), lineOrigins);
NSLog(@"line count = %ld",CFArrayGetCount(lines));
for (int i = 0; i < CFArrayGetCount(lines); i++) {
CTLineRef line = CFArrayGetValueAtIndex(lines, i);
CGFloat lineAscent;
CGFloat lineDescent;
CGFloat lineLeading;
CTLineGetTypographicBounds(line, &lineAscent, &lineDescent, &lineLeading);
NSLog(@"ascent = %f,descent = %f,leading = %f",lineAscent,lineDescent,lineLeading);
CFArrayRef runs = CTLineGetGlyphRuns(line);
NSLog(@"run count = %ld",CFArrayGetCount(runs));
for (int j = 0; j < CFArrayGetCount(runs); j++) {
CGFloat runAscent;
CGFloat runDescent;
CGPoint lineOrigin = lineOrigins[i];
CTRunRef run = CFArrayGetValueAtIndex(runs, j);
NSDictionary* attributes = (NSDictionary*)CTRunGetAttributes(run);
CGRect runRect;
runRect.size.width = CTRunGetTypographicBounds(run, CFRangeMake(0,0), &runAscent, &runDescent, NULL);
NSLog(@"width = %f",runRect.size.width);
runRect=CGRectMake(lineOrigin.x + CTLineGetOffsetForStringIndex(line, CTRunGetStringRange(run).location, NULL), lineOrigin.y - runDescent, runRect.size.width, runAscent + runDescent);
NSString *imageName = [attributes objectForKey:@"imageName"];
//圖片渲染邏輯
if (imageName) {
UIImage *image = [UIImage imageNamed:imageName];
if (image) {
CGRect imageDrawRect;
imageDrawRect.size = image.size;
imageDrawRect.origin.x = runRect.origin.x + lineOrigin.x;
imageDrawRect.origin.y = lineOrigin.y;
CGContextDrawImage(context, imageDrawRect, image.CGImage);
}
}
}
}
CFRelease(ctFrame);
CFRelease(path);
CFRelease(ctFramesetter);
}
效果:

從上面看大家可能沒(méi)有發(fā)現(xiàn)什么問(wèn)題,當(dāng)把圖片放在字的最左邊會(huì)是什么樣子的?

因此為了避免這種情況發(fā)生,我在代碼中添加了換行模式。添加換行后的效果:

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
HTTP/2 協(xié)議用于 iOS 推送提醒服務(wù) (APNS)
基于JSON的請(qǐng)求和響應(yīng)對(duì)于每個(gè)通知,如果成功響應(yīng),將會(huì)返回200標(biāo)識(shí) - 不用再去猜測(cè)通知是否被接收到響應(yīng)錯(cuò)誤將會(huì)以JSON字符消息的長(zhǎng)度從2048個(gè)字節(jié)增加到4096個(gè)字節(jié)連接狀態(tài)可以通過(guò)HTTP/2的ping框架來(lái)進(jìn)行檢查.2016-04-04
iOS實(shí)現(xiàn)左右拖動(dòng)抽屜效果
這篇文章主要介紹了iOS實(shí)現(xiàn)左右拖動(dòng)抽屜效果,理解ios平臺(tái)類似于QQ主頁(yè)面,利用觸摸事件滑動(dòng)touchesMoved實(shí)現(xiàn)的效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02
iOS中模態(tài)Model視圖跳轉(zhuǎn)和Push視圖跳轉(zhuǎn)的需求實(shí)現(xiàn)方法
這篇文章主要介紹了iOS中模態(tài)Model視圖跳轉(zhuǎn)和Push視圖跳轉(zhuǎn)的需求實(shí)現(xiàn),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12
iOS表視圖之下拉刷新控件功能的實(shí)現(xiàn)方法
下拉刷新是重新刷新表視圖或列表,以便重新加載數(shù)據(jù),這種模式廣泛用于移動(dòng)平臺(tái),相信大家對(duì)于此也是非常熟悉的,那么iOS是如何做到的下拉刷新呢?下面小編給大家分享iOS表視圖之下拉刷新控件的實(shí)現(xiàn)方法,一起看看吧2017-01-01
iOS runtime forwardInvocation詳解及整理
這篇文章主要介紹了 iOS runtime forwardInvocation詳解及整理的相關(guān)資料,需要的朋友可以參考下2017-02-02
iOScollectionView廣告無(wú)限滾動(dòng)實(shí)例(Swift實(shí)現(xiàn))
本篇文章主要介紹了iOScollectionView廣告無(wú)限滾動(dòng)實(shí)例,可以實(shí)現(xiàn)廣告無(wú)限滾動(dòng),有興趣的可以了解一下。2016-11-11
iOS App引導(dǎo)頁(yè)開(kāi)發(fā)教程
這篇文章主要為大家詳細(xì)介紹了iOS App引導(dǎo)頁(yè)開(kāi)發(fā)教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
iOS應(yīng)用開(kāi)發(fā)中的文字選中操作控件UITextView用法講解
這篇文章主要介紹了iOS應(yīng)用開(kāi)發(fā)中的文字選中操作控件UITextView用法講解,代碼基于傳統(tǒng)的Objective-C語(yǔ)言,需要的朋友可以參考下2016-02-02

